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

发布于 2024-08-31 11:49:29 字数 1464 浏览 12 评论 0原文

我有这个简单的接口/类:

public abstract class Message {}

public class Message1 extends Message {}

public class Message2 extends Message {}

和一个实用程序类:

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");
    }
}

现在,主类:

public static void main(String[] args) {

    Utility p = new Utility();

    Message1 m1 = new Message1();
    p.handler(m1);

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

}

输出是

> Class: Message1
> Interface: Message

我希望 p.handler(m) 调用方法 p.handler(m: Message1)

我不想使用“手动”命令 instanceof 因为我有很多情况:

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

如果我调用 m.getClass() 我获得“mypackage .Message1”,因此是子类而不是超类。

我尝试使用此代码(使用反射):

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

但输出是

> Interface: Message

所以,这是我的问题。我会在运行时将超类对象转换为子类对象,而不使用“代码命令”istanceof。

我想要一个像这样的正确命令:

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

我怎样才能获得它?有可能吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肤浅与狂妄 2024-09-07 11:49:29

Java 将根据编译时已知的信息来调用该方法。您可以做的就是向接口添加一个方法,该方法调用对象的正确处理程序方法。

public abstract class Message {

    public abstract void callHandler(Utility utility);

}

public class Message1 extends Message{

    public void callHandler(Utility utility) {
        utility.handler(this);
    }
}

您对处理程序的调用变为:

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

现在调用 Utility::handler(Message1),即使 main 中的引用属于 Message 接口的类型。

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.

何止钟意 2024-09-07 11:49:29

我不确定你的handle(..)方法应该做什么,但由于它们依赖于Message的特定实例,你应该考虑将handle()方法添加到你的Message类中(作为抽象方法)。这样,每个消息都会实现其句柄版本,并且您可以享受多态性的好处:

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

此代码将根据您的需要返回“Class:Message1”。

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). 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文