Java: On object created event - java

Is there something that I can do to simulate "on created" event?
I have a base class which other people can extend, and currently I have an init() that will initialize the instance, but it should be called only after the constructor stack completes.
If I call init() in the base class' constructor, then I might potentially initialize wrongly, because the subclass' constructor has not finished executing. The subclass can initialize values of some of the protected fields, which would have an impact on how init() initializes the instance.
My current approach is to make init() protected final, and asks that subclasses must call it at the end of their constructor. This approach works, but only provided if subclasses really do follow the instruction.
Edit
I thought I would give some extra information. This is part of a JavaFX project/custom API. So I had tried using Platform.runLater(() -> init()), which was a major mistake. Platform.runLater() would only run after the whole execution stack completes, which causes the usage of uninitialized instance in this case:
Foo instance = new Foo();
instance.doSomething();

There is no easy way to force a method call in the end of subclass constructor. This may be doable via annotation processor, which let you modify source code at precompile time. But it will be complicated. I think instead of subclassing, your goal can be better achieved using factory pattern instead.
You can define a few setters to let users initialize your fields, then call init in the end of your factory method.

Related

Reference overridden method in supertype constructor

I'm trying to find a solution for a project assignment. Basically I have created a class which is derivative of another abstract class. In it's construction I'm trying to call the supertype constructor with a string and an integer as argument. The issue is that I'm trying to calculate the integer value in an overridden method in the same class. Like so:
super(name, getBaseValue());
This doesn't work because I can't reference the method within the supertype constructor. Maybe I have simply misunderstood the assignment and the UML-diagram. Any ideas how to go about solving this?
getBaseValue() must be static and also use this.getBaseValue (), so that it looks like this:
super(name, this.getBaseValue());
You probably shouldn't do that at all. At the time the constructor runs, the object is not yet created (it's still in the process of being created), and calling a method on it is risky because that method may assume the object is fully created. Even worse, a derived class could also define that method, and then you the parent constructor isn't even done when a child class' method is already called --- chaos.
You can call static methods (which don't require an object instance being created), or you can hard-code any values you want to pass.
See also MET05-J. Ensure that constructors do not call overridable methods in the Secure Java Coding Standard and Sonar Source's warning about this.

what's the difference between class type variables or instantiating in a constructor/method

public class MotoXCellPhone {
//assume there's a speaker class
private BlueToothSpeaker speaker;
//why instantiate in constructor?
MotoXCellPhone() {
speaker = new BlueToothSpeaker();
}
//or if i instantiate in a method?
public BlueToothSpeaker useSpeaker() {
speaker = new BlueToothSpeaker();
return speaker;
}
}
why would i want to instantiate a class in another class' constructor? i don't fully understand composition yet so i'm fuzzy on the 'why" of everything
If you instantiate it in the method, you'll create a new one each time that method is called. If that doesn't make sense -- if you want one BlueToothSpeaker object to be tied to the MotoXCellPhone object for its lifetime -- then you need to create it (or inject it) in the constructor.
The argument is as follows: if someone else uses your code, they might not call useSpeakser() and thus speakers might be null. Instantiating speakers within the constructor asserts that it will not be null.
The constructor will run and instantiate BlueToothSpeaker right when MotoXCell is instantiated, whereas the method will only instantiate the new class when it is called.
There are two types of member initialization, each with pros and cons, I'll try to enumerate them:
early-initialization:
done when declaring the member, or within the class constructor
pros:
the created object begins it's lifecycle at the same time as it's "parent", and is available at any time without needing to do any checks
in the case of a worker class, the created object can start working right away
cons:
more CPU/memory used for that object
depending on the context the object might never be used
lazy-initialization:
done on demand, usually within its getter
pros:
the object will be created only when firstly needed, thus reduces its CPU/memory usage
no context dependent, if the member is not needed at all, it will not be created
cons:
you will need to always access the member via it's getter within the "parent" class, otherwise you might run into crashes
care must be taken when dealing with multithreading (e.g. a lock must be used), and this has a performance impact
Depending of the implementation of your class you might choose one over another.

singleton class doesn't work

I have been going through this tutorial and from what I understand, a singleton class can only be initialized once. Therefore I wrote the following 1 line of code:
public synchronized static DefaultHttpClient getThreadSafeClient {
**System.out.println("this should only happen once!!");**
I then wrote the following lines of code in my MainActivity's button:
HttpClient httpclient = multithreaded_httpclient.getThreadSafeClient();
HttpClient httpclient1 = multithreaded_httpclient.getThreadSafeClient();
I then pressed the button many times and to my surprise i found this in my logcat:
this should only happen once
this should only happen once
this should only happen once
this should only happen once
I thought singleton classe's method only executes once... how is this possible ?
It seems there is a small misunderstanding related to Singletons.
Singletons can only be initialized once, meaning there can only be one instance of it. Of course, the static method will be executed each time you call it, but the returned instance will always be the very same one.
In a nutshell, the Singletons pattern means that:
The constructor of your class is private
You create a public factory method, where YOU take care of:
If it is the first time that an instance is requested, create an instance with new YourClass()
If an instance was already created in a previous call, you don't create a new one, but return the previous one.
So, when any other class needs an instance of that class, they are enforced to call that factory method, since the constructor is private, and inside of that method, you write the code to ensure there is only one instance.
Thats all. With this only one object can be created, so all the possible instances of the object are actually the same, but of course any call to any public method of that object will be normally executed, no matter how many times it is called.

In Eclipse's Java debugger, how can I set a breakpoint on every object creation of some class?

I would like to have Eclipse's Java debugger debug-suspend the monitored process whenever an object of a particular type (class / interface) gets instantiated.
As a workaround, I can set breakpoints
on all constructors of that type
on all constructors of that type's supertypes and subtypes
but
this is awkward
neglects instantiation with the default constructor
may cause false-positive debug suspensions on object instantiations of classes I didn't want to suspend on.
You shouldn't need to set breakpoints on superclasses and subclasses. If you put a breakpoint on every constructor of the class you are interested in then every time an object of that class or a subclass of it is created the debugger will hit one of the breakpoints.
This doesn't work for interfaces because they are never constructed. I can't think of a way of doing it for interfaces.
Remember that the default constructor only exists for a class if you don't define any constructor at all, so as long as you have at least one constructor it won't be possible to instantiate an object of that type without using one of the constructors you have written.
See this answer of Carlos Heuberger on this thread.
You can also set a breakpoint on particular class load if you need it. See this tutorial for reference

Is it possible to call the default-constructor instead of the zero-argument constructor?

I have a util class that is supposed to call a method on a given Class object using reflection.
Right now it creates a new instances using .newInstance() and then calls the method I want to test.
The problem is that the zero-arguement constructor of some of my classes throws an Exception due to missing dependencies and such and keeps me from calling the method I actually want to test.
Is it possible to call the default-constructor of Java to create the instance instead of the custom zero-argument constructor?
You only have a default constructor, if the class has no constructors defined.
The no-arg constructor should only take the dependencies you give it (i.e. none) and it appears you believe you can still use the class without additional dependencies.
In Sun/Oracle JVM you can use Unsafe.allocateInstance(Class) which creates an instance without calling a constructor, but I would try to fix your class design first.
A default constructor is only created, when you don't provide a constructor yourself.
So, as soon as your class has at least one constructor, that default constructor isn't being created.

Categories