Preventing a method being called before another one - java

This is question is a bit broad and conceptual.
I have a class with various methods. Let's call them A and B. How can I make sure that other developers working with this class in the future will not call method B before first calling method A at least once ?
I am doing this in C++ but in general what's the best way to enforce this ? I have naive some ideas such as using a boolean variable but I would like to hear some other thoughts as well.

One way to guarantee this? Make it the responsibility of method B to call method A once.
Anything else is a fragile API.

One way is to redesign your class a little differently. Consider a simple database class that needs to be initialized before being used. I'm a Java guy, so...
public class Database {
public void init(String username, String password) // must call this first!
public List<Object> runQuery(String sql) // ...
}
So I need to call init first. I can make a DatabaseFactory that does the initialization and returns the actual database object. We can hide the constructor so that only a DatabaseFactory can create a Database (in Java a nested class, in C++ a friend class maybe?).
public class DatabaseFactory {
public Database init(String username, String password) // ...
public class Database {
private Database() {}
public List<Object> runQuery(String sql) // ...
}
}
So now I must go through the Factory to get to the underlying object.
DatabaseFactory factory = new DatabaseFactory();
Database database = factory.init("username", "password"); // first init (call method A)
// now I can use database (or B in your case)
database.runQuery("select * from table");

Have a boolean variable that determines if A has been called. Then, when someone tries to invoke B without this boolean variable being set, throw an IllegalStateException.
Or you could have B simply call A since it seems that it cannot execute without A being called first anyways.
Otherwise, and since both methods are public, there's really no other way to enforce this.

Using a boolean is a good start, and throwing on access works OK.
However sometimes its nice to be able to enforce this at compile-time. In that case your only real option is to use some tricks.
Only expose A in your class, make it return a proxy containing B.
class MyClass {
public:
struct BProxy {
public:
MyClass * root;
void B() { root->B(); }
protected:
BProxy( MyClass * self ) : root(self) {}; // Disable construction
friend class MyClass; //So that MyClass can construct it
};
BProxy A() { ... return BProxy(this); }
friend class BProxy; // So that BProxy can call B()
protected
void B() { ... }
};
int main() {
MyClass m;
BProxy bp = m.A();
// m.B(); can't do this as it's private - will fail at compile time.
bp.B(); // Can do this as we've got the proxy from our previous call to A.
}
You can also achieve something similar using protected inheritance from a baseclass implementing (or providing a virtual) B().

One way to guarantee it is that A is done in the constructor of the class. If the constructor fails (throws) then the other developers do not have anything with what to do that erroneous B with. If the constructor succeeds then A is done at least once and so B is valid operation to do.

I would make method "A" the constructor to initialise the object. This has to called once to use the object, enforced by the compiler. Later you can call a method "B" in the knowledge that a constructor must have been called.

Related

Call method once after any one of a few overloaded methods are called

In an abstract class I have a Predicate field, that is meant to be a combination of an unknown number of other Predicates. Joining the predicates works just fine but I am trying to have some way to know when the predicate has been initialized (or rather, just a way to know if it has or hasn't been initted).
Here is a short example of what I'm talking about:
public abstract class LimitedSystem implements Moveable {
private Predicate<Double> limits;
private final boolean initialized;
public void setLimits(SingleLimit... limits) {
List<Predicate<Double>> limitsList = Arrays.asList(limits);
this.limits = limitsList.stream().reduce(Predicate::and).orElse(x -> true);
}
public void setLimits(TwoLimits limits) {
this.limits = limits;
}
...
I am looking for ways to set initialized to true once (and once only, hence the final. I think I used it right) any of the setLimits have been called (they're overloaded).
I have other setLimits methods, but for the sake of generic code, I don't want to put a initialized at the end of each of the overloaded methods.
So my question is how can I, in a generic way, set the value of initialized after any of the setLimits methods has been called.
My first idea was to try to wrap the setLimits in some generic method which would call the correct overload by the parameter it gets, and then change initialized in that method. But I am not sure if that's a good idea.
Some other idea I got from another question1 was to put the setLimits in some interface or something similar. But I'm not sure how useful that might prove.
So how might this be accomplished?
(Also, if you happen to notice any design problems in this, please tell me because I'm trying to improve in that matter)
There's no need for separate fields:
private Predicate<Double> limits;
private final boolean initialized;
is basically
private Optional<Predicate<Double>> limits = Optional.empty();
if you want initialized to be set to true once limits is set,
provided you can guarantee that none of the setLimits methods can set it to Optional.empty() again. initialized == limits.isPresent().
You can't guarantee that a method is called in the body of an overridden method; in any case, this is a variant of the Call super antipattern.
You can do it like this:
abstract class Base {
final void setFoo(Object param) { // final, so can't be overridden.
setFooImpl(param);
thingThatMustBeCalled();
}
protected abstract void setFooImpl(Object param);
final void thingThatMustBeCalled() { ... }
}
class Derived extends Base {
#Override protected void setFooImpl(Object param) { ... }
}
But it's pretty ugly.

Delegate method calling in Java

In Java: What is the best way to pass a method from one object to another so that it can be called at a later time by the second object?
I come from an ActionScript background where it is as easy to pass around references to methods as it is to pass around references to variables but this seems to be much more difficult in Java. The first few links I found flat out say it is not possible (and it may have been at the time of their posting), but then I found http://www.javacamp.org/javavscsharp/delegate.html which details how this can be accomplished.
My issue with using Javacamp's example is the string based reference to the method. Methods get renamed all the time and a string reference will only complain once you actually run that function runtime as opposed to compile time for a proper explicit link.
Is there no way to do this with proper explicit links to the method you want the other class to execute?
Model of what I am hoping to accomplish:
Player clicks an upgrade button on Activity1 > Activity1 passes upgrade method to a new confirmation activity
Player clicks "Yes" > Confirmation activity calls upgrade method passed in from Activity1
OR: Player clicks "No" > Confirmation Activity closes
EDIT:
To be clear I am not looking for a static method solution as that would require my Confirmation activity to hold many lines of logic for which static method to call. The Confirmation activity will be used all over my application: a simple "Are you sure you want to X?" -Yes -No, if yes execute X
I am currently looking at implementing onActivityResult to avoid this issue but that will be more logic than I like for this kind of issue.
you can use interfaces like this:
public interface MyMethod {
public void method();
}
public class FirtObject{
private SecondObject ob;
public void tellSecondObjectExecuteLater(){
ob.executeLater( new MyMethod() {
public void method(){System.out.println("duh Method");} });
}
}
public class SecondObject {
private MyMethod myMth;
public void executeLater(MyMethod mth){
myMth = mth;
}
public void executeNow(){
myMth.method();
}
}
does this solve your problem?
The typical way to pass methods is to use an Interface and Anonymous Inner Classes. In order to maintain static typing an Interface is used to declare the method signature and typing information. The caller can use either a concrete implementation of that interface as a normal class or using Anonymous Inner Classes for quick class creation. I'll use standard Java SDK classes to illustrate:
interface Comparator<T> {
public int compare( T a, T b);
}
class SpecialCollection<T> {
public void sort( Comparator<T> comparator ) {...}
}
public class SomeClient {
public void doSomething( SpecialCollection<SpecialObj> collection ) {
collection.sort( new Comparator<SpecialObj>() {
public int compare( SpecialObject a, SpecialObject b ) {
// some implementation
}
} );
}
}
The above is an example of a strategy pattern. The thing about the strategy pattern (and passing callback methods like in Javascript). The author has to plan for those types of extensions. The author has to predict up front where he/she wants you to extend. And it just happens it's cleanest if you use Interfaces.
However, pure delegation doesn't have to have always involve Interfaces. You can pass concrete classes, since Java can always pass a subclass that overrides various methods of that class to change what method or code will be invoked. For example in Java InputStream/OutputStream are abstract classes and you typically pass subclass instances to the methods.
If you need the method to act differently depending on the context (AKA, it is different depending on how it is created), you'll want to pass along the instance of the class that the method is in.
If it is a static method, you can just referenced the method itself if you import that class at the top of your new class.
For example, lets say you have a method that will tell you stuff about a certain string. IF the class looks like this:
class stringChecker {
private String stringToCheck;
public class stringChecker(String s) {
stringToCheck = s;
}
public int getStringLength() {
return stringToCheck.length();
}
public boolean stringStartsWith(String startsWith) {
return (stringToCheck.indexOf(startsWith) == 0);
}
}
Then you'll want to pass along the instance, since it is non-static. Different instances have different strings that they were created with, so you will get a different return if you use a different instance.
However, if your class looks more like this:
class stringChecker {
public static int getStringLength(String s) {
return s.length();
}
public static boolean stringStartsWith(String s, String startsWith) {
return (s.indexOf(startsWith) == 0);
}
}
Then you can just reference those methods with stringChecker.getStringLength("test");, because the methods are static. It doesn't matter what instance they are in. The returned result depends ONLY on what is being passed in. You just have to make sure to add import stringChecker; at the top or whatever your class will be called. For you, it'll probably be something like com.example.blah.otherthing.stringChecker, since you're working with android.
Good luck! I hope this helps :)
EDIT: Looks like I may have read the problem too quickly...if this isn't what you were asking about, just let me know with a comment and I'll delete this answer so as to not confuse anybody else.
You said that you are using it in a project to open a Confirmation activity.
Activities should not contain references to each other to avoid memory leaks. To pass data between activities should be used Intent class. To receive a result, call StartActivityForResult() and get result in the onActivityResult() method.
But in general for your task is more suitable AlertDialog or PopupWindow.

Java Overridable method call in constructor [duplicate]

I have a Wicket page class that sets the page title depending on the result of an abstract method.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
NetBeans warns me with the message "Overridable method call in constructor", but what should be wrong with it? The only alternative I can imagine is to pass the results of otherwise abstract methods to the super constructor in subclasses. But that could be hard to read with many parameters.
On invoking overridable method from constructors
Simply put, this is wrong because it unnecessarily opens up possibilities to MANY bugs. When the #Override is invoked, the state of the object may be inconsistent and/or incomplete.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() {
overrideMe();
}
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) {
this.x = x;
}
#Override
void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class’s constructor
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
On object construction with many parameters
Constructors with many parameters can lead to poor readability, and better alternatives exist.
Here's a quote from Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters:
Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameters, a third with two optional parameters, and so on...
The telescoping constructor pattern is essentially something like this:
public class Telescope {
final String name;
final int levels;
final boolean isAdjustable;
public Telescope(String name) {
this(name, 5);
}
public Telescope(String name, int levels) {
this(name, levels, false);
}
public Telescope(String name, int levels, boolean isAdjustable) {
this.name = name;
this.levels = levels;
this.isAdjustable = isAdjustable;
}
}
And now you can do any of the following:
new Telescope("X/1999");
new Telescope("X/1999", 13);
new Telescope("X/1999", 13, true);
You can't, however, currently set only the name and isAdjustable, and leaving levels at default. You can provide more constructor overloads, but obviously the number would explode as the number of parameters grow, and you may even have multiple boolean and int arguments, which would really make a mess out of things.
As you can see, this isn't a pleasant pattern to write, and even less pleasant to use (What does "true" mean here? What's 13?).
Bloch recommends using a builder pattern, which would allow you to write something like this instead:
Telescope telly = new Telescope.Builder("X/1999").setAdjustable(true).build();
Note that now the parameters are named, and you can set them in any order you want, and you can skip the ones that you want to keep at default values. This is certainly much better than telescoping constructors, especially when there's a huge number of parameters that belong to many of the same types.
See also
Wikipedia/Builder pattern
Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters (excerpt online)
Related questions
When would you use the Builder Pattern?
Is this a well known design pattern? What is its name?
Here's an example which helps to understand this:
public class Main {
static abstract class A {
abstract void foo();
A() {
System.out.println("Constructing A");
foo();
}
}
static class C extends A {
C() {
System.out.println("Constructing C");
}
void foo() {
System.out.println("Using C");
}
}
public static void main(String[] args) {
C c = new C();
}
}
If you run this code, you get the following output:
Constructing A
Using C
Constructing C
You see? foo() makes use of C before C's constructor has been run. If foo() requires C to have a defined state (i.e. the constructor has finished), then it will encounter an undefined state in C and things might break. And since you can't know in A what the overwritten foo() expects, you get a warning.
Invoking an overridable method in the constructor allows subclasses to subvert the code, so you can't guarantee that it works anymore. That's why you get a warning.
In your example, what happens if a subclass overrides getTitle() and returns null ?
To "fix" this, you can use a factory method instead of a constructor, it's a common pattern of objects instanciation.
Here is an example that reveals the logical problems that can occur when calling an overridable method in the super constructor.
class A {
protected int minWeeklySalary;
protected int maxWeeklySalary;
protected static final int MIN = 1000;
protected static final int MAX = 2000;
public A() {
setSalaryRange();
}
protected void setSalaryRange() {
throw new RuntimeException("not implemented");
}
public void pr() {
System.out.println("minWeeklySalary: " + minWeeklySalary);
System.out.println("maxWeeklySalary: " + maxWeeklySalary);
}
}
class B extends A {
private int factor = 1;
public B(int _factor) {
this.factor = _factor;
}
#Override
protected void setSalaryRange() {
this.minWeeklySalary = MIN * this.factor;
this.maxWeeklySalary = MAX * this.factor;
}
}
public static void main(String[] args) {
B b = new B(2);
b.pr();
}
The result would actually be:
minWeeklySalary: 0
maxWeeklySalary: 0
This is because the constructor of class B first calls the constructor of class A, where the overridable method inside B gets executed. But inside the method we are using the instance variable factor which has not yet been initialized (because the constructor of A has not yet finished), thus factor is 0 and not 1 and definitely not 2 (the thing that the programmer might think it will be). Imagine how hard would be to track an error if the calculation logic was ten times more twisted.
I hope that would help someone.
If you call methods in your constructor that subclasses override, it means you are less likely to be referencing variables that don’t exist yet if you divide your initialization logically between the constructor and the method.
Have a look on this sample link http://www.javapractices.com/topic/TopicAction.do?Id=215
I certainly agree that there are cases where it is better not to call some methods from a constructor.
Making them private takes away all doubt: "You shall not pass".
However, what if you DO want to keep things open.
It's not just the access modifier that is the real problem, as I tried to explain here. To be completely honest, private is a clear showstopper where protected usually will still allow a (harmful) workaround.
A more general advice:
don't start threads from your constructor
don't read files from your constructor
don't call APIs or services from your constructor
don't load data from a database from your constructor
don't parse json or xml documents from your constructor
Don't do so (in)directly from your constructor. That includes doing any of these actions from a private/protected function which is called by the constructor.
Calling an start() method from your constructor could certainly be a red flag.
Instead, you should provide a public init(), start() or connect() method. And leave the responsibility to the consumer.
Simply put, you want to separate the moment of "preparation" from the "ignition".
if a constructor can be extended then it shouldn't self-ignite.
If it self-ignites then it risks being launched before being fully constructed.
After all, some day more preparation could be added in the constructor of a subclass. And you don't have any control over the order of execution of the constructor of a super class.
PS: consider implementing the Closeable interface along with it.
In the specific case of Wicket: This is the very reason why I asked the Wicket
devs to add support for an explicit two phase component initialization process in the framework's lifecycle of constructing a component i.e.
Construction - via constructor
Initialization - via onInitilize (after construction when virtual methods work!)
There was quite an active debate about whether it was necessary or not (it fully is necessary IMHO) as this link demonstrates http://apache-wicket.1842946.n4.nabble.com/VOTE-WICKET-3218-Component-onInitialize-is-broken-for-Pages-td3341090i20.html)
The good news is that the excellent devs at Wicket did end up introducing two phase initialization (to make the most aweseome Java UI framework even more awesome!) so with Wicket you can do all your post construction initialization in the onInitialize method that is called by the framework automatically if you override it - at this point in the lifecycle of your component its constructor has completed its work so virtual methods work as expected.
I guess for Wicket it's better to call add method in the onInitialize() (see components lifecycle) :
public abstract class BasicPage extends WebPage {
public BasicPage() {
}
#Override
public void onInitialize() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}

What's wrong with overridable method calls in constructors?

I have a Wicket page class that sets the page title depending on the result of an abstract method.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
NetBeans warns me with the message "Overridable method call in constructor", but what should be wrong with it? The only alternative I can imagine is to pass the results of otherwise abstract methods to the super constructor in subclasses. But that could be hard to read with many parameters.
On invoking overridable method from constructors
Simply put, this is wrong because it unnecessarily opens up possibilities to MANY bugs. When the #Override is invoked, the state of the object may be inconsistent and/or incomplete.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() {
overrideMe();
}
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) {
this.x = x;
}
#Override
void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class’s constructor
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
On object construction with many parameters
Constructors with many parameters can lead to poor readability, and better alternatives exist.
Here's a quote from Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters:
Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameters, a third with two optional parameters, and so on...
The telescoping constructor pattern is essentially something like this:
public class Telescope {
final String name;
final int levels;
final boolean isAdjustable;
public Telescope(String name) {
this(name, 5);
}
public Telescope(String name, int levels) {
this(name, levels, false);
}
public Telescope(String name, int levels, boolean isAdjustable) {
this.name = name;
this.levels = levels;
this.isAdjustable = isAdjustable;
}
}
And now you can do any of the following:
new Telescope("X/1999");
new Telescope("X/1999", 13);
new Telescope("X/1999", 13, true);
You can't, however, currently set only the name and isAdjustable, and leaving levels at default. You can provide more constructor overloads, but obviously the number would explode as the number of parameters grow, and you may even have multiple boolean and int arguments, which would really make a mess out of things.
As you can see, this isn't a pleasant pattern to write, and even less pleasant to use (What does "true" mean here? What's 13?).
Bloch recommends using a builder pattern, which would allow you to write something like this instead:
Telescope telly = new Telescope.Builder("X/1999").setAdjustable(true).build();
Note that now the parameters are named, and you can set them in any order you want, and you can skip the ones that you want to keep at default values. This is certainly much better than telescoping constructors, especially when there's a huge number of parameters that belong to many of the same types.
See also
Wikipedia/Builder pattern
Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters (excerpt online)
Related questions
When would you use the Builder Pattern?
Is this a well known design pattern? What is its name?
Here's an example which helps to understand this:
public class Main {
static abstract class A {
abstract void foo();
A() {
System.out.println("Constructing A");
foo();
}
}
static class C extends A {
C() {
System.out.println("Constructing C");
}
void foo() {
System.out.println("Using C");
}
}
public static void main(String[] args) {
C c = new C();
}
}
If you run this code, you get the following output:
Constructing A
Using C
Constructing C
You see? foo() makes use of C before C's constructor has been run. If foo() requires C to have a defined state (i.e. the constructor has finished), then it will encounter an undefined state in C and things might break. And since you can't know in A what the overwritten foo() expects, you get a warning.
Invoking an overridable method in the constructor allows subclasses to subvert the code, so you can't guarantee that it works anymore. That's why you get a warning.
In your example, what happens if a subclass overrides getTitle() and returns null ?
To "fix" this, you can use a factory method instead of a constructor, it's a common pattern of objects instanciation.
Here is an example that reveals the logical problems that can occur when calling an overridable method in the super constructor.
class A {
protected int minWeeklySalary;
protected int maxWeeklySalary;
protected static final int MIN = 1000;
protected static final int MAX = 2000;
public A() {
setSalaryRange();
}
protected void setSalaryRange() {
throw new RuntimeException("not implemented");
}
public void pr() {
System.out.println("minWeeklySalary: " + minWeeklySalary);
System.out.println("maxWeeklySalary: " + maxWeeklySalary);
}
}
class B extends A {
private int factor = 1;
public B(int _factor) {
this.factor = _factor;
}
#Override
protected void setSalaryRange() {
this.minWeeklySalary = MIN * this.factor;
this.maxWeeklySalary = MAX * this.factor;
}
}
public static void main(String[] args) {
B b = new B(2);
b.pr();
}
The result would actually be:
minWeeklySalary: 0
maxWeeklySalary: 0
This is because the constructor of class B first calls the constructor of class A, where the overridable method inside B gets executed. But inside the method we are using the instance variable factor which has not yet been initialized (because the constructor of A has not yet finished), thus factor is 0 and not 1 and definitely not 2 (the thing that the programmer might think it will be). Imagine how hard would be to track an error if the calculation logic was ten times more twisted.
I hope that would help someone.
If you call methods in your constructor that subclasses override, it means you are less likely to be referencing variables that don’t exist yet if you divide your initialization logically between the constructor and the method.
Have a look on this sample link http://www.javapractices.com/topic/TopicAction.do?Id=215
I certainly agree that there are cases where it is better not to call some methods from a constructor.
Making them private takes away all doubt: "You shall not pass".
However, what if you DO want to keep things open.
It's not just the access modifier that is the real problem, as I tried to explain here. To be completely honest, private is a clear showstopper where protected usually will still allow a (harmful) workaround.
A more general advice:
don't start threads from your constructor
don't read files from your constructor
don't call APIs or services from your constructor
don't load data from a database from your constructor
don't parse json or xml documents from your constructor
Don't do so (in)directly from your constructor. That includes doing any of these actions from a private/protected function which is called by the constructor.
Calling an start() method from your constructor could certainly be a red flag.
Instead, you should provide a public init(), start() or connect() method. And leave the responsibility to the consumer.
Simply put, you want to separate the moment of "preparation" from the "ignition".
if a constructor can be extended then it shouldn't self-ignite.
If it self-ignites then it risks being launched before being fully constructed.
After all, some day more preparation could be added in the constructor of a subclass. And you don't have any control over the order of execution of the constructor of a super class.
PS: consider implementing the Closeable interface along with it.
In the specific case of Wicket: This is the very reason why I asked the Wicket
devs to add support for an explicit two phase component initialization process in the framework's lifecycle of constructing a component i.e.
Construction - via constructor
Initialization - via onInitilize (after construction when virtual methods work!)
There was quite an active debate about whether it was necessary or not (it fully is necessary IMHO) as this link demonstrates http://apache-wicket.1842946.n4.nabble.com/VOTE-WICKET-3218-Component-onInitialize-is-broken-for-Pages-td3341090i20.html)
The good news is that the excellent devs at Wicket did end up introducing two phase initialization (to make the most aweseome Java UI framework even more awesome!) so with Wicket you can do all your post construction initialization in the onInitialize method that is called by the framework automatically if you override it - at this point in the lifecycle of your component its constructor has completed its work so virtual methods work as expected.
I guess for Wicket it's better to call add method in the onInitialize() (see components lifecycle) :
public abstract class BasicPage extends WebPage {
public BasicPage() {
}
#Override
public void onInitialize() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}

Is it possible to do computation before super() in the constructor?

Given that I have a class Base that has a single argument constructor with a TextBox object as it's argument. If I have a class Simple of the following form:
public class Simple extends Base {
public Simple(){
TextBox t = new TextBox();
super(t);
//wouldn't it be nice if I could do things with t down here?
}
}
I will get a error telling me that the call to super must be the first call in a constructor. However, oddly enough, I can do this.
public class Simple extends Base {
public Simple(){
super(new TextBox());
}
}
Why is it that this is permited, but the first example is not? I can understand needing to setup the subclass first, and perhaps not allowing object variables to be instantiated before the super-constructor is called. But t is clearly a method (local) variable, so why not allow it?
Is there a way to get around this limitation? Is there a good and safe way to hold variables to things you might construct BEFORE calling super but AFTER you have entered the constructor? Or, more generically, allowing for computation to be done before super is actually called, but within the constructor?
Thank you.
Yes, there is a workaround for your simple case. You can create a private constructor that takes TextBox as an argument and call that from your public constructor.
public class Simple extends Base {
private Simple(TextBox t) {
super(t);
// continue doing stuff with t here
}
public Simple() {
this(new TextBox());
}
}
For more complicated stuff, you need to use a factory or a static factory method.
I had the same problem with computation before super call. Sometimes you want to check some conditions before calling super(). For example, you have a class that uses a lot of resources when created. the sub-class wants some extra data and might want to check them first, before calling the super-constructor. There is a simple way around this problem. might look a bit strange, but it works well:
Use a private static method inside your class that returns the argument of the super-constructor and make your checks inside:
public class Simple extends Base {
public Simple(){
super(createTextBox());
}
private static TextBox createTextBox() {
TextBox t = new TextBox();
t.doSomething();
// ... or more
return t;
}
}
It is required by the language in order to ensure that the superclass is reliably constructed first. In particular, "If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass."
In your example, the superclass may rely on the state of t at construction time. You can always ask for a copy later.
There's an extensive discussion here and here.
You can define a static supplier lambda which can contain more complicated logic.
public class MyClass {
private static Supplier<MyType> myTypeSupplier = () -> {
return new MyType();
};
public MyClass() {
super(clientConfig, myTypeSupplier.get());
}
}
The reason why the second example is allowed but not the first is most likely to keep the language tidy and not introduce strange rules.
Allowing any code to run before super has been called would be dangerous since you might mess with things that should have been initialized but still haven't been. Basically, I guess you can do quite a lot of things in the call to super itself (e.g. call a static method for calculating some stuff that needs to go to the constructor), but you'll never be able to use anything from the not-yet-completely-constructed object which is a good thing.
This is my solution that allows to create additional object, modify it without creating extra classes, fields, methods etc.
class TextBox {
}
class Base {
public Base(TextBox textBox) {
}
}
public class Simple extends Base {
public Simple() {
super(((Supplier<TextBox>) () -> {
var textBox = new TextBox();
//some logic with text box
return textBox;
}).get());
}
}
That's how Java works :-) There are technical reasons why it was chosen this way. It might indeed be odd that you can not do computations on locals before calling super, but in Java the object must first be allocated and thus it needs to go all the way up to Object so that all fields are correctly initialized before you can modify them.
In your case there is most of the time a getter that allows you to access the parameter you gave to super(). So you would use this:
super( new TextBox() );
final TextBox box = getWidget();
... do your thing...

Categories

Resources