所以,这是一个古怪的问题。我在嵌入式环境中工作,我正在尝试从一个应用程序向另一个应用程序发送消息(对象)。 API标准对象(如java.lang.String)可以正常工作,但是当我尝试发送自定义类的对象时,会引发ClassCastException。
这是设置:我有一个发送者应用程序和一个接收器应用程序。在发送方应用程序中,我实例化一个UserUAI对象(我编写的库中包含的自定义类),将其强制转换为Object,并使用环境API中包含的支持类ComManager将其发送到接收应用程序。但是没关系,它运行正常,就像我之前说的,如果我使用符合API的对象,我没有任何问题。
发送结束:
UserUAI userUAI = new userUAI(/*param list*/);
ComManager.getInstance().sendMessage(targetAppPID, userUAI);
//method signature: void sendMessage(String targetAppPID, Object message)
接收结束:
Object received = (UserUAI)receiver.getReceivedMessage();
UserUAI userUAI = (UserUAI)received; //raises exception
//method signature: Object getReceivedMessage();
我检查,双重检查和三重检查,收到的对象在运行时是UserUAI类型。
另外,我发布了PaŭloEbermann给我的建议的结果:
received.getClass() - > class nddigital.support.ricoh.UserUAI
UserUAI.class - > class nddigital.support.ricoh.UserUAI
received.getClass()。getClassLoader() - > jp.co.ricoh.dsdk.osgi.service.multiXletManager.XletClassloader@2d4f9e
UserUAI.class.getClassLoader - > jp.co.ricoh.dsdk.osgi.service.multiXletManager.XletClassloader@4464ab
UserUAC.class == received.getClass() - >假的
UserUAC.class.getClassLoader()== received.getClass()。getClassLoader() - >假
我希望那里的人可以伸出援助之手。我会告诉你的。
答案 0 :(得分:3)
要讨论§4.3.4的Java Specification部分
两种引用类型是相同的运行时类型,如果:
它们都是类或两种接口类型,由相同的类加载器定义, 并具有相同的二进制名称(§13.1),在这种情况下,它们有时被称为 相同的运行时类或相同的运行时接口。
它们都是数组类型,它们的组件类型是相同的运行时类型(第10节)。
如果T是类类型,那么R必须是相同的类(§4.3.4)作为T或 T的子类,或抛出运行时异常。
因此,由于不同的类加载器已经定义了相同的类,因此不能将其实例转换为其他类。
答案 1 :(得分:2)
从例外情况来看,receiver.getReceivedMessage()返回的对象显然不是UserUAI类型。如果此方法必须返回Object并且您无法更改它以返回特定类型以防止从对象进行盲目类型转换,那么至少您可以执行
Object received = receiver.getReceivedMessage();
if(received instanceof UserUAI)
{
UserUAI userUAI = (UserUAI) received;
}
以防止错误。
答案 2 :(得分:2)
从评论到其他答案,看起来你有类加载器问题。
试试这个:
Object received = receiver.getReceivedMessage();
System.out.println(received.getClass());
System.out.println(UserUAI.class);
System.out.println(received.getClass.getClassLoader());
System.out.println(UserUAI.class.getClassLoader());
System.out.println(UserUAI.class == received.class);
System.out.println(UserUAI.class.getClassLoader() == received.getClass.getClassLoader());
即使前两个输出看起来相同,如果由不同的类加载器加载,它们也是不同的类。
要解决此问题,我们需要更多关于您如何使用此内容的背景信息。
答案 3 :(得分:0)
它不起作用,因为receiver.getReceivedMessage()
返回的对象不是UserUAI
。您可以设置一个断点并确切地找出它返回的内容。
更好的方法是尽可能使用泛型。无法从您展示的代码中真正分辨出来。
答案 4 :(得分:0)
如上所述,返回的对象不是正确的类型。这是一种简单的方法来确定实际返回的对象类型。如果得到NullPointerException,则返回的对象为null
private Object o = receiver.getReceivedMessage();
System.out.println(o.getClass().getName());
答案 5 :(得分:0)
解决方案一直在我面前。我使UserUAI类可序列化并将其作为字节数组发送。在接收端,我反序列化它并将结果对象强制转换为UserUAI,它工作得很好。
Ishtar,感谢你的帖子,这是规范文本给了我这个想法。