简体   繁体   English

反射:将对象转换为子类而不使用instanceof

[英]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) 我希望p.handler(m)调用方法p.handler(m:Message1)

I don't want use the "manual" command instanceof because I have many cases: 我不想使用“手动”命令instanceof因为我有很多情况:

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. 如果我调用m.getClass()我获得“mypackage.Message1”,所以子类而不是超类。

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. 我会做一个超类对象的运行时强制转换为subclassobject而不使用“code command”istanceof。

I would a right command like this: 我会这样一个正确的命令:

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

How can I obtain it? 我怎样才能获得它? It's possible? 这是可能的?

Java will call the method on the basis of information known at compile time. Java将根据编译时已知的信息调用该方法。 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. 现在调用Utility :: handler(Message1),即使main中的引用是Message接口的类型。

I am not sure what your handle(..) methods are supposed to do, but since they depend on the specific instance of Message, you should consider adding handle() method to your Message class (as abstract method). 我不确定你的handle(..)方法应该做什么,但由于它们依赖于Message的特定实例,你应该考虑在你的Message类中添加handle()方法(作为抽象方法)。 This way, each message implements its version of handle, and you can enjoy the benefits of polymorphism: 这样,每条消息都实现了它的句柄版本,你可以享受多态的好处:

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

This code will return "Class: Message1", as you need. 此代码将根据需要返回“Class:Message1”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM