Reflection: pouring an object into a subclass without using instanceof

I have this simple interface / class:

public abstract class Message {} public class Message1 extends Message {} public class Message2 extends Message {} 

And utility class:

 public class Utility { public void handler(Message m) { System.out.println("Interface: Message"); } public void handler(Message1 m) { System.out.println("Class: Message1"); } public void handler(Message2 m) { System.out.println("Class: Message2"); } } 

Now the main class:

 public static void main(String[] args) { Utility p = new Utility(); Message1 m1 = new Message1(); p.handler(m1); Message m = (Message) m1; p.handler(m); } 

Output signal

 > Class: Message1 > Interface: Message 

I would like p.handler(m) call the p.handler(m:Message1)

I do not want to use the "manual" instanceof command because I have many cases:

 if(m instance of Message1) p.handler((Message1)m) else if (m instanceof Message2) p.handler((Message2)m) ... 

If I call m.getClass() , I get "mypackage.Message1", therefore a subclass, not a superclass.

I am trying to use this code (use reflection):

 p.handler(m.getClass().cast(m)); 

But the conclusion

 > Interface: Message 

So this is my problem. I would run a superclass of a subclassobject without using the "code command" istanceof command.

I would make the correct command as follows:

 p.handler((m.getclass)m); 

How can I get it? Is it possible?

+4
source share
2 answers

Java will call a method based on information known at compile time. What you can do is add a method to the interface that calls the correct handler method for the object.

 public abstract class Message { public abstract void callHandler(Utility utility); } public class Message1 extends Message{ public void callHandler(Utility utility) { utility.handler(this); } } 

Your calls to the handler become:

 Message m=(Message) m1; m.callHandler(p); 

which now calls the Utility :: handler (Message1), even if the link is basically of the Message interface type.

+7
source

I'm not sure what your handle (..) methods should do, but since they depend on the specific Message instance, you should consider adding the handle () method to your Message class (as an abstract method). Thus, each message implements its own version of the descriptor, and you can take advantage of polymorphism:

 Message m = new Message1(); m.handle(); 

This code will return "Class: Message1" as you need.

0
source

Source: https://habr.com/ru/post/1308982/


All Articles