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;
}
}
Related
I was wondering if it's frowned upon that when designing an framework to be used by others, a class has some function as default behavior and expects its customers to override it if necessary. An example would be something like the following:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
// process record logic
}
}
Consumers of this library creates their concrete classes to process their own records of type T.
Now I want to add a function called preProcess() to offer the ability for the consumers to preprocess their records. It would then look something like this:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
preprocess();
// process record logic
}
public void preProcess() {
// By default no preprocessing
}
}
I know I can make preProcess an abstract function, but I dont want to due to a couple reasons:
Not all customers need to preprocess their records
We have a pipeline structure that autodeploys pushed code, so making RecordProcessor an abstract class would immediately break our customers' applications.
Is making preProcess do nothing in the parent class and let child classes override it considered bad practice? If not, what should the best way be to let customers know that they now have the power to preprocess the records? Through java docs?
One approach is to mark the public method as final (but this might also break existing apps) and allow protected hook methods to be overridden. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void process() {
doPreProcess();
doProcess();
doPostProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Having some documentation should make it natural for other developers to recognize the optional extension methods.
I don't see anything wrong with having a hook method which does nothing. However, it should contain a return statement so static analysis tools won't complain.
UPDATE: in order to avoid breaking existing apps, if possible mark the existing method as deprecated and introduce a new method. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void execute() {
doPreProcess();
doProcess();
doPostProcess();
}
#Deprecated - use execute() method instead.
public void process() {
doProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Prefer composition over inheritance. If you want your clients to add custom pre processing then do it by delegating to a separate objects.
public interface RecordPreProcessor<T extends Record>{
public void process(T record);
}
public class RecordProcessor<T extends Record> {
private RecordPreProcessor<T> recordPreProcessor = null;
public void setRecordPreProcessor(RecordPreProcessor<T> recordPreProcessor) {
this.recordPreProcessor = recordPreProcessor;
}
public void process() {
if (recordPreProcessor != null) recordPreProcessor.process(record);
// process record logic
}
}
No, overriding is not discouraged in Java.
The language allows overriding.
The language makes all methods overridable by default.
The Java class library includes examples of the same pattern.
Your approach is one reasonable way to allow subclasses to extend the behavior of their parent class. There are alternatives, such as passing a behavior as an object. However, there is no one true way.
One way you could improve your code is to mark preProcess() as protected. It's an implementation detail of the class. You don't want just anyone holding a RecordProcessor to decide they can call preProcess() by itself, right?
public class RecordProcessor<T extends Record> {
...
protected void preProcess() {
^^^^^^^^^
// By default no preprocessing
}
}
Another way to improve this is to consider whether you intend anyone to create an instance of the superclass RecordProcessor. If you don't, make the class abstract, to prevent that. The class name can express that, if you like, or your coding guidelines call for it.
public abstract class AbstractRecordProcessor<T extends Record> {
^^^^^^^^ ^^^^^^^^
...
protected void preProcess() {
// By default no preprocessing
}
}
One common way to document such methods is with the phrase "The default implementation does nothing. Subclasses may override this method ...". For example, below is the documentation for java.util.concurrent.FutureTask.done(). You can find more examples by searching for the first sentence of that phrase online.
public class FutureTask<V> implements RunnableFuture<V> {
...
/**
* Protected method invoked when this task transitions to state
* {#code isDone} (whether normally or via cancellation). The
* default implementation does nothing. Subclasses may override
* this method to invoke completion callbacks or perform
* bookkeeping. Note that you can query status inside the
* implementation of this method to determine whether this task
* has been cancelled.
*/
protected void done() { }
}
What I ended up doing- which I also thought was pretty good, inspired by #tsolakp, was simply creating a child class to RecordProcessor, called something like PreprocessRecordProcessor. This has no way of interfering existing code because nothing existing was touched. The class would something like this:
public class PreprocessRecordProcessor<T extends Record> extends RecordProcessor<T> {
// ...
public void process() {
preProcess();
super.process();
}
protected abstract void preProcess();
}
And if customers of this library would like to add their own logic they can simply extend this class and they'd be forced to provide pre-processing logic (as supposed to having the option to provide, which may result in unexpected results if they forgot to.)
I have a method which adds Objects to an static list like this:
#PostConstruct
protected void registerToTransactionList() {
TransactionValidator.registerTransactionList(this);
}
registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:
#Override
#PostConstruct
protected void registerToTransactionList() {
}
It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.
make the method private to block the visibility
private void registerToTransactionList() {
}
or make the method final to block it from been override
protected final void registerToTransactionList() {
}
There are two ways of achieving that:
Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
Change your whole logic and make that method private
It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.
So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).
And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!
Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!
EDIT: after some more thinking, I guess you are doing things "the wrong way", like:
class BaseClass {
public final void doRegistration() {
BaseClass toRegister = getObjectForRegistration();
if (toRegister != null) { ... register toRegister ...
}
protected BaseClass getObjectForRegistration() {
return null;
}
With that code, you could then put
protected BaseClass getObjectForRegistration() {
if (this instanceof ClassThatShouldBeRegistered) {
return this;
}
return null;
}
into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.
I really hope I am just missing something simple, but I am reading the following: http://docs.oracle.com/javase/tutorial/java/IandI/override.html .
I have two classes and one interface. Literally the "use case" shown in this Oracle documentation page. However, when I run a JUnit test - only the method in the superclass gets called and that method has the simple default that I don't want called:
The interface contains this method signature:
public interface RecordServiceInterface {
List<String> searchRecords(String id) throws ServiceException;
}
The superclass which implements the interface contains this method with a default - Eclipse IDE inserts this when it finds a missing method not implemented by the implementing class.
public class RecordService implements RecordServiceInterface {
public List<String> searchRecords(String id) throws ServiceException {
// TODO Auto-generated method stub
return null;
}
}
At runtime, only the above is called as I step through the debugger... every time.
The subclass then extends the superclass and has the real implementation that one wants to override:
public class MyRecordService extends RecordService {
#Override
public List<String> searchRecords(String id) throws ServiceException {
List<String> myList = new ArrayList<String>();
// ...
return myList;
}
}
I must be completely missing the point of #Override. During execution, it repeatedly fails to ever get into the method with the #Override annotation.
All that the #Override annotation does is make the compiler generate an error if there is no corresponding method anywhere in the class inheritance that could be overridden. So it is meant to make sure that your overridden method actually overrides something.
If your method from MyRecordService is not called, but the one from the RecordService class, then I would guess that the wrong object is instanciated. So what you have in front of you is an object of type RecordService, not of type MyRecordService.
Since you have not provided that part of the code, this is just a guess, based on the fact that your inheritance looks fine.
#Override is a compile-time annotation and is used to verify that the annotated method actually overrides something from a superclass / interface. It does not influence runtime behavior.
Post the code for your test so we can get a clearer idea of what you're trying to do.
As you can see in #Override's javadoc, the retention policy of #Override is SOURCE. In other words: it used in compile time but does not make it to the generated binary code (class file).
In particular, the SOURCE retention policy is defined as:
Annotations are to be discarded by the compiler.
#Override is effectively just a way to catch typos when attempting to override a super class' or instance's method, as well as the occasional attempt to override final methods (by design not overridable).
The act of overriding enables a fall-thru approach to overriding method when given a choice of what to call.
For example:
RecordServiceInterface service = new RecordService();
RecordService service2 = new RecordService();
With both service and service2, the implementation from RecordService will be called. Now consider:
RecordServiceInterface service3 = new MyRecordService();
RecordService service4 = new MyRecordService();
MyRecordService service5 = new MyRecordService();
With service3, service4, and service5, the implementation from MyRecordService will be called.
Overriding does not replace methods for parent types unless it is part of the chain (e.g., all three of the instances created in the last block, 3 through 5). If the instance of your Object does is not the type (MyRecordService in this case), then the method is not overridden for that instance with its behavior. service and service2 will still call RecordService's implementation.
It may be more clear with another example:
public interface Runnable {
void run();
}
public class RunnableA implements Runnable {
#Override
public void run() { System.out.println("A"); }
}
public class RunnableB extends RunnableA {
#Override
public void run() { System.out.println("B"); }
}
public class RunnableC implements Runnable {
#Override
public void run() { System.out.println("C"); }
}
You can only have an instance of any one of them, so it will only output one line per call of instance.run(). It depends on the implementation of the instance, and not what exists on the classpath.
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()
I would like to override a method in an object that's handed to me by a factory that I have little control over.
My specific problem is that I want to override the getInputStream and getOutputStream of a Socket object to perform wire logging.
The generic problem is as follows:
public class Foo {
public Bar doBar() {
// Some activity
}
}
Where I'd like to take an instantiated Foo and replace the doBar with my own that would work as follows:
Bar doBar() {
// My own activity
return original.doBar();
}
For the Socket I'm going to return an InputStream and OutputStream that are wrapped by logging to intercept the data.
Since Java uses class-based OO, this is impossible. What you can do is use the decorator pattern, i.e. write a wrapper for the object that returns the wrapped streams.
I think there is a way to achieve the effect you want. I saw it orriginally used in swing with buttons to allow the programmer to make the button do something when it is clicked.
Say you have your Foo class:
public class Foo {
public Bar doBar() {
// Some activity
}
}
Then you have a runner class or something similar. You can override the doBar() method at the point of instantiation and it will only affect that specific object.
that class may look like this:
public class FooInstance{
Foo F1 = new Foo(){
public Bar doBar(){
//new activity
}
}
Foo F2 = new Foo();
F1.doBar(); //does the new activity
F2.doBar(); //does the original activity found in the class
}
I'm not entirely sure that will do the trick for you but maybe it'll set you in the right direction. If nothing else it is possible to override a method outside of the class, maybe that will help you.
You can't replace methods in existing objects - you can't change an existing object's type, for one thing.
You could create a new instance of another class which delegated to the existing instance, but that has limitations too.
In your real world case is there no way you can simply make a separate call to wrap the streams returned by the socket? Can you give more details.
You can't really change an object on the fly in java.
You could have something which do what you want by wrapping your Foo into another similar objet which will delegate every call to Foo and at the same log everything you want. (see Proxy)
But if you want to do logging, maybe aspect is a better choice. (see AspectJ)
Using a decorator is the right way to go:
Some very similar code to the requirement you have with sockets is here:
http://www.javaspecialists.eu/archive/Issue058.html
Another proxying-related solution: you could use Aspects to override a method on a given object without subclassing it yourself. This is especially appropriate and common for logging. This example uses spring-aop.
class Example {
final Foo foo;
Example(Foo original) {
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(original);
factory.addAspect(FooAspect.class);
foo = (Foo) factory.getProxy();
}
#Aspect
static class FooAspect {
#Before("execution(Foo.doBar())")
Object beforeDoBar() {
// My own activity
}
}
If Socket was an interface then you could create a dynamic proxy. Below is an example. I put this here in case other people need to do this and the target instance is an instance of an interface.
The main reason this will not work for Socket is because java.lang.reflect.Proxy.newProxyInstance requires an array of interfaces for its second argument, so classes won't work here. As such for this example I had to create an interface called ParentInterface, which just has the three print methods.
public class Parent implements ParentInterface {
#Override
public void print1() {
System.out.println("parent 1");
}
#Override
public void print2() {
System.out.println("parent 2");
}
#Override
public void print3() {
System.out.println("parent 3");
}
public static void main(String[] args) {
Parent originalInstance = new Parent();
ParentInterface proxied = (ParentInterface) java.lang.reflect.Proxy.newProxyInstance(
Parent.class.getClassLoader(),
new Class[]{ParentInterface.class},
new ParentProxy(originalInstance));
proxied.print1();
proxied.print2();
proxied.print3();
}
static class ParentProxy implements InvocationHandler {
final Object realObject;
public ParentProxy(Object real) {
realObject = real;
}
#Override
public Object invoke(Object target, Method m, Object[] args) throws Throwable {
try {
if (m.getName().equals("print2")) {
print2();
return null;
} else {
return m.invoke(realObject, args);
}
} catch (java.lang.reflect.InvocationTargetException e) {
throw e.getTargetException();
}
}
public void print2() {
System.out.println("wrapper 2");
}
}
}
I'm not sure if this is possible. Have you considered creating your own class, having the object returned by the factory as a member, and then writing the doBar() method for that class.
two options:
easy : if Foo were you implemetn an interface you can use a Dynamic proxy to add new functionality.
more work: what you have is an "around" advice of AOP - you can use any of the existing AOP tools to make that possible. Spring Framework can do it for you, if you are using it already.