Is there something like #PostConstruct in plain java? - java

I have an class A and B like this:
public static class A {
public A() {
System.out.println("A");
}
public void init() {
System.out.println("RUN AFTER CONSTRUCTOR");
}
}
public static class B extends A {
public B() {
System.out.println("B");
}
}
public static void main(String[] args) {
new B();
}
I want that A and all subclasses of A run a piece of code AFTER the constructor has finished.
Is it possible without adding Spring/AspectJ or something like that?

No. Plain Java doesn't provide similarly hook methods.
#PostConstruct available in bean containers was initially designed to perform an init processing after dependency injection is done.
As the container performs for you the instantiation (and the destruction) of the beans, it has so a way to execute code after their instantiation (or before their destruction : #PreDestroy).
But i don't want to repeat it in every subclass, and it should be
called after even the subclass constructor has finished
If each constructor invocation of the hierarchy has to perform a specific processing, you have to specify that in each class or base class.

As #DavidBrossard said, on Vanilla Java, you can call init() at the end of the constructor, to execute like a #PostConstruct

Related

Check is instance method is called from a constructor

I would like to check, from an instance method of a non-final class, whether the constructors and initializers of that class and its chain of subclasses for the specific instance have already completed.
In the following example, I have a class Abstract, which can be used to implement an interface which allows listeners to be added (which, for simplicity, are just Runnable instances here) and which provides a method signalEvent() which calls all attached listeners.
abstract class Abstract {
protected final void signalEvent() {
// Check that constructs have run and call listeners.
}
public final void addListener(Runnable runnable) {
...
}
}
class Concrete extends Abstract {
Concrete() {
// Should not call signalEvent() here.
}
void somethingHappened() {
// May call signalEvent() here.
}
}
Now it is possible to call signalEvent() from within the subclass constructor, but there is no way that a listener has already been added by that time and the event would just be lost. In our code-base, once in a while, someone adds such a call and I would like to be able to catch such calls as early as possible (using an assert statement or similar).
Is it possible to check whether an instance method is being called, directly or indirectly, from the subclass constructor or initializer of the current instance or, alternatively, is it possible to check whether all constructors for an instance have been completed?
In short, there is no elegant Java mechanism that allows you to do that, but you may consider using a factory pattern. Instead of creating instances directly using new keyword, you could create a factory class, that takes care of creating the actual instance and invokes an additional "post-create" method, that lets the instance know it's been completely created.
If you're using some dependency injection like spring, you get that out of the box, but if not, a solution could look something like this:
interface PostConstruct { // the classes need to implement that
void postConstruct();
}
public class InstanceFactory {
public <T extends PostConstruct> T create(Class<T> clazz, Object... params) {
T instance = //create using reflection
instance.postConstruct();
return instance;
}
}
A solution to the problem to see if a method or code is being called from a constructor. The code below will print true and false respectivly but would be slow and not pretty at all.
I still believe it is not the right solution for the problem above. As Codbender said, better to check if a listener has been added or set a status variable which would be faster
Edit - fixed the issue that Codebender mentioned and also made sure to check back in the stack trace incase of being called a couple of methods deep
public class TestClass extends TestAbstract {
public TestClass() throws Exception {
submethod();
}
public void submethod() throws Exception {
System.out.println(isInConstructor());
}
public static void main(String[] args) throws Exception {
System.out.println(new TestClass().isInConstructor());
}
}
public class TestAbstract {
public boolean isInConstructor() throws Exception {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : elements) {
if (element.getMethodName().equals("<init>") &&
TestAbstract.class.isAssignableFrom(Class.forName(element.getClassName()))) {
return true;
}
}
return false;
}
}

Appropriate way to pass instance of class to other classes (Java)

I have a main class which has a number of instance related methods that are often needed in other classes and I often find myself passing an instance of the main class in the constructor. I often find this goes several layers deep with classes having instances of the main class that has been copied from instance to instance which I can't imagine is good for memory usage.
Is there a way to do this without having to pass the instance in the constructor or a method or at least a way to reduce the memory that is used by the instances of the main class.
To make it clear I am not looking for static methods, it is designed to be able to have more than one instance of the main class.
Example code:
public class Main {
public Main() {
Class2 class2 = new Class2(this);
}
public void someMethod() {
//Do something
}
}
public class Class2 {
private final Main instance;
public Class2(Main instance) {
this.instance = instance;
Class3 class3 = new Class3(instance);
}
}
public class Class3 {
private final Main instance;
public Class3(Main instance) {
this.instance = instance;
instance.someMethod();
}
}
You can use Dependency Injection Design Pattern.
Dependency-Injection-Design-Pattern
Spring, Google Guice and Java EE CDI frameworks facilitate the
process of dependency injection through use of Java Reflection API and
java annotations. All we need is to annotate the field, constructor or
setter method and configure them in configuration xml files or
classes.
You could also use dependency injection to pass on the dependent attributes or objects to required classes.
One such popular framework is Google Guice.
You could make methods like someMethod() in the Main class static, or if that's not possible, make the Main class itself a singleton.
Example of the former approach:
public class Main {
public Main() {
Class2 class2 = new Class2(this);
}
public static void someMethod() {
//Do something
}
}
Now you don't have to pass an instance of Main around any more, because other classes can just call Main.someMethod() directly.

Accessing parent class instance variables from child class instances

So right now, I have a Preprocessor class that generates a bunch of instance variable maps, and a Service class that has a setPreprocessor(Preprocessor x) method, so that an instance of the Service class is able to access the maps that the preprocessor generated.
At the moment, my Service class needs to call three methods in succession; for sake of simplicity, let's call them executePhaseOne, executePhaseTwo, and executePhaseThree. Each of these three methods instantiate/modify Service instance variables, some of which are pointers to the Service instance's Preprocessor object.
My code has this structure right now:
Preprocessor preprocessor = new Preprocessor();
preprocessor.preprocess();
Service service = new Service();
service.setPreprocessor(preprocessor);
service.executePhaseOne();
service.executePhaseTwo();
service.executePhaseThree();
To better organize my code, I want to put each executePhaseXXX() call in its own separate subclass of Service, and leave the common data structures for all the phases in the parent class Service. Then, I want to have an execute() method in the Service parent class that executes all three phases in succession:
class ServiceChildOne extends Service {
public void executePhaseOne() {
// Do stuff
}
}
class ServiceChildTwo extends Service {
public void executePhaseTwo() {
// Do stuff
}
}
class ServiceChildThree extends Service {
public void executePhaseThree() {
// Do stuff
}
}
EDIT:
The problem is, how do I write my execute() method in the Service parent class? I have:
public void execute() {
ServiceChildOne childOne = new ServiceChildOne();
ServiceChildTwo childTwo = new ServiceChildTwo();
ServiceChildThree childThree = new ServiceChildThree();
System.out.println(childOne.preprocessor); // prints null
childOne.executePhaseOne();
childOne.executePhaseTwo();
childOne.executePhaseThree();
}
However, my childOne, childTwo, and childThree objects aren't able to access the preprocessor instance variable that lives in the parent class Service... How could I get past this problem?
Use the protected modifier for your Preprocessor instance variable of Service, like so:
public class Service {
protected Preprocessor preprocessor;
}
Then each subclass of Service has a this.preprocessor.
you could provide some method like getPreprocessorInstance() in your Service class that returns Preprocessor instance
Your preprocessor should be protected or public to be able to have an access from the child.
You can read about modifiers here.
UPDATE
new ServiceChildOne(new Preprocessor());
.....
class ServiceChildOne extends Service {
public ServiceChildOne(Preprocessor preprocessor) {
super.preprocessor = preprocessor;
}
public void executePhaseOne() {
// Do stuff
}
}
It looks like your problem is that you have not one, but four different instances of Service - each of which has its own uninitialized copy of the base class variables.
The only solutions I can think of at the moment are, first, the rather poor design of making your Service member variables static - which, in effect, means you can only have one version of Service at a time. A better solution, to my mind, would be to not make the processing phases subclasses, but instead make them independent classes that take an instance of Service as a parameter.
EDIT:
For a quick example, the Service class could look like:
class Service
{
public Service() { ... }
public Preprocessor getPreprocessor() { ... }
public void setPreprocessor(Preprocessor preprocessor { ... }
public Type2 getVariable2() { ... }
public void setVariable2(Type2 variable2) { ... }
...
}
and the phase classes could look something like:
class ServicePhaseOne
{
private Service m_dataHost;
public ServicePhaseOne(Service dataHost)
{
m_dataHost = dataHost;
}
public void executePhaseOne()
{
// Do phase 1 stuff
}
}
... and so on for phase 2 and phase 3.
The execute() method would then look like:
public void execute()
{
ServicePhaseOne phaseOne = new ServicePhaseOne(this);
ServicePhaseTwo phaseTwo = new ServicePhaseTwo(this);
ServicePhaseThree phaseThree = new ServicePhaseThree(this);
phaseOne .executePhaseOne();
phaseTwo .executePhaseTwo();
phaseThree .executePhaseThree();
}

Guice injector inside a thread

I have a doubt using Guice. I have a class that I call Main that is constructor injected using Guice and a method that every time that is called creates an o thread object of class AppThread. AppThread is a private class inside Main. The problem is that inside the execution of the thread I want to create an object of class ClassX. This object is constructor injected using Guice. I don't know what's the best form to inject the objects of ClassX. My first solution is inject the Injector inside Main and inside the thread use the injector to inject the objects of class ClassX.
Does exists a cleaner approach to inject the dependences inside the thread?
Thanks
Instead of having your own subclass of Thread (which is discouraged anyway) you should write your "thread code" as a regular object that implements Runnable. Your Main class should inject this class (or you can actually inject a Provider<MyRunnable> if you need to instantiate an unknown number of them). Then your Main class can create a new Thread(myRunnable) and it should all fit together nicely.
public class MyMainClass {
#Inject
MyMainClass(Provider<MyRunnable> runnableProvider) { ... }
public void spawnThread() {
new Thread(runnableProvider.get()).start();
}
}
public class MyRunnable implements Runnable {
#Inject
MyRunnable(ClassX myX) { ... }
public void run() {
... do work ...
}
}

Java Method Overriding - accessing methods in parent - is this possible?

Let's say I create an instance of a class and override one of its methods at the same time - like this
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
}
};
Now let's imagine I want to call a local method which has the SAME name and SAME (lack of) parameters as my overridden method - e.g. I have
public void mymethod() {
//my stuff in here
}
How can I call that from within the overridden method (on the line //call something here)???
Is that even possible? Using
this.mymethod();
causes an endless loop (the overriden method is simply calling itself)
Is there a way of accessing this method (other than via a static reference perhaps?)
Sorry if this is a common question - it's a hard thing to search for and the one question I found had no replies and wasn't really that well-phrased so I'm trying myself!!
I don't have a complier handy so I'm not 100% sure here, but try this:
ParentClass.this.myMethod();
An ugly, but functioning solution:
final MyOtherClass parent = this;
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
parent.mymethod();
}
};
I'm struggling to see the scenario where you need to do this for naming purposes, but it's useful to know that this in the anonymous class will refer to the anonymous class, not the "parent"; so if you find the need to access the parent's method it's a useful technique.
FWIW, here's a working example.
I am not sure if I fully understood the question but my guess is that you want something like this:
public class ParentClass {
public void mymethod() {
....
}
public void someOtherMethod() {
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
ParentClass.this.mymethod();
}
}
}
}
Note ParentClass.this.mymethod()

Categories