How to call an empty constructor from another? - java

I have some code like so:
public class Foo {
private int x;
public Foo() {
}
public Foo(int x) {
try {
//do some initialisation stuff like:
this.x = x;
}
catch(Exception ge){
//call empty constructor not possible
//this();
//this.EMPTY();
//Foo();
}
}
public static final Foo EMPTY = new Foo();
}
I'd like to know if it is possible to achieve something such as this (I know that calling another constructor must be the first statement in the constructor).
I have looked around here on SO but haven't found anything as such, leading me to believe that perhaps, I ought to handle the error logic in the instantiating method.

Just change the execution order :
public class Foo {
Integer i;
public Foo() {
System.out.println("Empty constructor invoked");
}
public Foo(Integer i) {
this(); //can be omitted
try {
System.out.println("i initialized to : "+i.toString());
} catch (Exception ex) {
System.out.println("i NOT initialized ");
}
}
public static void main(String[] args) {
new Foo(); //prints: Empty constructor invoked
new Foo(5);//prints: Empty constructor invoked
//prints: i initialized to : 5
new Foo(null);//prints: Empty constructor invoked
//prints: i NOT initialized
}
}

In general, it isn't great practice to call code which could throw in a constructor, and worse then suppress the exception from the caller altogether. However, what you could do is refactor your code so that you move the 'default' initialization of the parameterless constructor into a helper method, which you can then call from your exception handler in the second constructor:
public class Foo {
private int x;
public Foo() {
doDefaultInitialize();
}
public Foo(int x) {
try {
// dodgy code which could throw
}
catch(Exception ge){
doDefaultInitialize();
}
}
private void doDefaultInitialize() {
// Fallback initialization goes here
x = 42;
}
}

As you said
calling another constructor must be the first statement in the
constructor
There are 2 solution I usually use when I need this behavior:
Make an init function and call it from both places:
public class Foo {
private int x;
public Foo() {
init();
}
public Foo(int x) {
try {
//do some initialisation stuff like:
this.x = x;
}
catch(Exception ge){
init();
}
}
private init() {
//Do the default initialization here...
}
public static final Foo EMPTY = new Foo();
}
Make a static function to initialize the object and return it.
public class Foo {
private int x;
private Foo() {
this.x = 42;
}
private Foo(int x) throws Exception {
//do some initialization stuff like:
this.x = x;
}
public static Foo getNewInstance(int x) {
try {
return new Foo(x);
} catch (Exception e) {
return new Foo();
}
}
public static final Foo EMPTY = getNewInstance();
}

Just do nothing in the catch block in the constructor. It should work as you want.
However, do have a look at this try-catch-in-constructor-recommended-practice for choosing the right approach to your problem.
Also, if you are doing any default initializations, then follow the approach mentioned by #StuartLC

Related

Using try catch constructor chain java

I have a class constructor and I need to perform a clone. From what I've read the best choice is to use a copy constructor, just like in C++. However, I've got an issue. If my "regular" constructor throws exceptions and such exceptions aren't even possible in a "copy constructor" how to I implement a try-catch if the first statement must be this.
public class X
{
public X() throws MyException
{
}
public X(final X original)
{
try {
this();
} catch (MyException e)
{
}
}
}
Is the only option add throws MyException to copy constructor?
Copy all data to a new instance by constructor could look like this:
public class X
{
// some Fields....
int a, b, c;
public X() { }
public X(final X originalX) throws InvalidArgumentException
{
if(originalX == null) {
throw new InvalidArgumentException("originalX should not be null!");
}
this.a = originalX.getA();
//...
}
// getter-setter....
}
And it´s called like this in main() or where ever else:
// x_1 is filles with Data...
X x_2;
try {
x_2 = new X(x_1);
} catch(InvalidArgumentException ex) {
LOG.reportError(ex.getMessage());
x_2 = new X(); // prevent NullPointer for usage afterwards
}

No enclosing instance is in scope with double brace initializers

I have some classes nested one in another
public abstract class I
{
public abstract int f();
}
public class J
{
private List<I> li;
public J(List<I> l)
{
li = l;
}
}
public class A // first class
{
private int x; // field of A
public class B extends J // second class
{
public B()
{
super(new ArrayList<I>() // super call
{{ // array initializer
add(new I() // third class
{
#Override
public int f()
{
return x; // <- here!!!
}
});
}});
}
}
}
Under these conditions, I get the error: "error: no enclosing instance of type A is in scope". Removing any element from this setup fixes this error. Also, taking x and saving it to another variable then using that variable also works.
What is happening here? It seems like a bug in a compiler for me.
It is not allowed to have 2 public classes in one Java File and file name should be same as public class name.
To experiment with your code I made a new Test class like this. I see no errors reported (using Java 8). Perhaps this is a build issue.
public class Test {
public abstract class I {
public abstract int f();
}
public class J {
private List<I> li;
public J(List<I> l) {
li = l;
}
}
public class A // first class
{
private int x; // field of A
public class B extends J // second class
{
public B() {
super(new ArrayList<I>() // super call
{
{ // array initializer
add(new I() // third class
{
#Override
public int f() {
return x; // <- here!!!
}
});
}
});
}
}
}
public void test() {
System.out.println("Hello");
}
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc="test">
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
//</editor-fold>
}
}
Java 7 also seems to accept this code.

Call a method after the constructor has ended

I need to call a method after the constructor has ended, and I have no idea what is the better approach.
I have this class:
class A {
public A() {
// ...
}
public void init() {
// call after the constructor
}
}
How do I call init() after the class A has been created?
You either have to do this on the client side, as so:
A a = new A();
a.init();
or you would have to do it in the end of the constructor:
class A {
public A() {
// ...
init();
}
public final void init() {
// ...
}
}
The second way is not recommended however, unless you make the method private or final.
Another alternative may be to use a factory method:
class A {
private A() { // private to make sure one has to go through factory method
// ...
}
public final void init() {
// ...
}
public static A create() {
A a = new A();
a.init();
return a;
}
}
Related questions:
What's wrong with overridable method calls in constructors?
Java call base method from base constructor
You will need a static factory method to construct the object, call the init method, and finally return the object:
class A {
private A() {
//...
}
private void init() {
//Call after the constructor
}
public static A create() {
A a = new A();
a.init();
return a;
}
}
Notice I have made the constructor and the init() method private, so that they can only be accessed by the factory method. Client code would make objects by calling A.create() instead of calling the constructor.
What did you so far? Are you looking something like this?
Class A {
public A() {
//...
}
public void init() {
//Call after the constructor
}
}
public static void main(String[] args)
{
A a = new A();
a.init();
}
I pick up some ideas and provide an abstractable solution:
class A {
protected A() {
// ...
}
protected void init() {
// ...
}
public static <T extends A> T create(Class<T> type) {
try {
T obj = type.newInstance();
obj.init();
return obj;
} catch (ReflectiveOperationException ex) {
System.err.println("No default constructor available.");
assert false;
return null;
}
}
}
If you want to call method BEFORE constructor you can use initializer block. https://www.geeksforgeeks.org/g-fact-26-the-initializer-block-in-java/
class A {
{
init()
}
public A() {
//todo
}
private final void init() {
//todo
}
}
Why not this :
Class A {
public A() {
//... Do you thing
this.init();
}
public void init() {
//Call after the constructor
}
}

Access methods based on constructor provided

In my program, I want to be able to access certain methods based on the constructor I initialize and nothing else. For example:
public class A {
int paramOne;
float paramTwo;
public A(int paramOne) {
// Constructor One
}
public A(float paramTwo) {
// Constructor Two
}
public void ConstructorOneMethodOnly(int paramOne) {
// Only used when Constructor One is initialized
}
public void ConstructorTwoMethodOnly(float paramTwo) {
// Only used when Constructor Two is initialized
}
}
In the code given, is there a way of achieving what I have described in the comments and in my question? If so, can you describe how to do so?
As per Sotirios Delimanolis' comment, you can not restrict the accessibility of a method based on the constructor used.
I think this logic should be divided into two class, that is the more clear implementation I can find out.
public class IntDemo {
int paramOne;
public IntDemo (int paramOne) {
...
}
public void ConstructorOneMethodOnly(int paramOne) {
...
}
}
class FloatDemo {
float paramTwo;
public FloatDemo(float paramTwo) {
...
}
public void ConstructorTwoMethodOnly(float paramTwo) {
...
}
}
public class A {
int paramOne;
float paramTwo;
int constr = 0;
public A(int paramOne) {
// Constructor One
constr = 1;
}
public A(float paramTwo) {
// Constructor Two
constr = 2;
}
}
and check constr variable before invoking methods.
Im not sure if this directly helps you but it may help you and more.
I suggest using a generic class like this.
public class A<T> {
public A(final T t) {
}
public void method(final T t) {
}
}
If you dont know how to use a generic class here is an exmaple
final A<Integer> aInteger = new A<Integer>(1);
final A<Float> aFloat = new A<Float>(5.4f);
Hope this helped!

Java: Anonymous inner class using a local variable

How can I get the value of userId passed to this method in my anonymous inner subclass here?
public void doStuff(String userID) {
doOtherStuff(userID, new SuccessDelegate() {
#Override
public void onSuccess() {
Log.e(TAG, "Called delegate!!!! "+ userID);
}
});
}
I get this error:
Cannot refer to a non-final variable userID inside an inner class defined in a different method
I'm pretty sure I can't assign it as final since it's a variable with an unknown value. I had heard that this syntax does preserve scope in some way, so I think there must be a syntax trick I don't quite know yet.
As everyone else here has said, local variables have to be final to be accessed by an inner class.
Here is (basically) why that is... if you write the following code (long answer, but, at the bottom, you can get the short version :-):
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
foo.bar();
}
}
the compiler translates it roughly like this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
class $1
implements Foo
{
public void bar()
{
System.out.println(x);
}
}
foo = new $1();
foo.bar();
}
}
and then this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new $1(x);
foo.bar();
}
private static class $1
implements Foo
{
private final int x;
$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
}
and finally to this:
class Main
{
public static void main(String[] args)
{
final int x;
Main$Foo foo;
x = 42;
foo = new Main$1(x);
foo.bar();
}
}
interface Main$Foo
{
void bar();
}
class Main$1
implements Main$Foo
{
private final int x;
Main$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
The important one is where it adds the constructor to $1. Imagine if you could do this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
x = 1;
foo.bar();
}
}
You would expect that foo.bar() would print out 1 but it would actually print out 42. By requiring local variables to be final this confusing situation cannot arise.
Sure you can assign it as final - just put that keyword in the declaration of the parameter:
public void doStuff(final String userID) {
...
I'm not sure what you meant about it being a variable with an unknown value; all that final means is that once a value is assigned to the variable, it cannot be re-assigned. Since you're not changing the value of the userID within your method, there's no problem making it final in this case.
In Java 8, this has changed a little bit. You can now access variables that are effectively final. Relevant snippet and example from the Oracle documentation (emphasis mine):
However, starting in Java SE 8, a local class can access local
variables and parameters of the enclosing block that are final or
effectively final.
Effectively final: A non-final variable or parameter whose value is never changed after it is initialized is effectively final.
For example, suppose that the variable numberLength is not declared final, and you
add the highlighted assignment statement in the PhoneNumber
constructor:
PhoneNumber(String phoneNumber) {
numberLength = 7; // From Kobit: this would be the highlighted line
String currentNumber = phoneNumber.replaceAll(
regularExpression, "");
if (currentNumber.length() == numberLength)
formattedPhoneNumber = currentNumber;
else
formattedPhoneNumber = null;
}
Because of this assignment statement, the variable numberLength is not
effectively final anymore. As a result, the Java compiler generates an
error message similar to "local variables referenced from an inner
class must be final or effectively final" where the inner class
PhoneNumber tries to access the numberLength variable:
if (currentNumber.length() == numberLength)
Starting in Java SE 8, if you declare the local class in a method, it
can access the method's parameters. For example, you can define the
following method in the PhoneNumber local class:
public void printOriginalNumbers() {
System.out.println("Original numbers are " + phoneNumber1 +
" and " + phoneNumber2);
}
The method printOriginalNumbers accesses the parameters
phoneNumber1 and phoneNumber2 of the method validatePhoneNumber
What's the problem with making it final as in
public void doStuff (final String userID)
declare the method
public void doStuff(final String userID)
The value needs to be final so that the compiler can be sure it doesn't change. This means the compiler can bind the value to the inner class at any time, without worrying about updates.
The value isn't changing in your code so this is a safe change.

Categories

Resources