Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection: cast an object to subclass without use instanceof

I have this simple interface/class:

public abstract class Message {}

public class Message1 extends Message {}

public class Message2 extends Message {}

And an 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);

}

The output is

> Class: Message1
> Interface: Message

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

I don't want use the "manual" command instanceof 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 obtain "mypackage.Message1", so the subclass and not the superclass.

I try with this code (use reflection):

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

But the output is

> Interface: Message

So, this is my problem. I would do a runtime cast of superclass object to subclassobject without use the "code command" istanceof.

I would a right command like this:

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

How can I obtain it? It's possible?

like image 430
jfabrizio Avatar asked May 06 '10 10:05

jfabrizio


People also ask

Can you cast a superclass to a subclass?

You can always successfully cast a superclass to a subclass. An interface can be a separate unit and can be compiled into a bytecode file. The order in which modifiers appear before a class or a method is important. Every class has a toString() method and an equals() method.

Does Instanceof check subclass?

As the name suggests, instanceof in Java is used to check if the specified object is an instance of a class, subclass, or interface.

How do you check if an object is a specific subclass?

The java “instanceof” operator is used to test whether the object is an instance of the specified type (class or subclass or interface). It is also known as type comparison operator because it compares the instance with type. It returns either true or false.

How do you find the instance of a class using reflection?

We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.


1 Answers

Java will call the method on the basis of information known at compile time. What you could 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 Utility::handler(Message1) even though the reference in main is of type of the Message interface.

like image 200
rsp Avatar answered Sep 23 '22 20:09

rsp