将java.lang.Object强制转换为自定义对象会引发ClassCastException
所以,这是一个奇怪的问题。我在一个嵌入式环境中工作,我试图将消息(对象)从一个应用程序发送到另一个应用程序。API标准对象(如java.lang.String)可以正常工作,但当我尝试向自定义类发送对象时,会引发ClassCastException 设置如下:我有一个发送方应用程序和一个接收方应用程序。在sender应用程序中,我实例化了一个UserUAI对象(我编写的库中包含的自定义类),将其转换为object,并使用环境API中包含的支持类ComManager将其发送到接收应用程序。但这没关系,它工作得很好,就像我之前说的,如果我使用符合API的对象,我就不会有任何问题 发送端:将java.lang.Object强制转换为自定义对象会引发ClassCastException,java,casting,Java,Casting,所以,这是一个奇怪的问题。我在一个嵌入式环境中工作,我试图将消息(对象)从一个应用程序发送到另一个应用程序。API标准对象(如java.lang.String)可以正常工作,但当我尝试向自定义类发送对象时,会引发ClassCastException 设置如下:我有一个发送方应用程序和一个接收方应用程序。在sender应用程序中,我实例化了一个UserUAI对象(我编写的库中包含的自定义类),将其转换为object,并使用环境API中包含的支持类ComManager将其发送到接收应用程序。但这没关
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ŭlo Ebermann)给我的一个建议的结果:
received.getClass()->class nddigital.support.ricoh.UserUAI
UserUAI.class->class nddigital.support.ricoh.UserUAI
已收到.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()->false
UserUAC.class.getClassLoader()==received.getClass().getClassLoader()->false
我希望外面有人能帮我一把。我会随时通知您。它不起作用,因为由
receiver.getReceivedMessage()
返回的对象不是用户UAI
。您可以设置一个断点并准确地找出它返回的内容
如果可能的话,更好的方法是使用泛型。无法从您显示的代码中真正分辨出来。它不起作用,因为
receiver.getReceivedMessage()
返回的对象不是用户UAI
。您可以设置一个断点并准确地找出它返回的内容
如果可能的话,更好的方法是使用泛型。从您显示的代码中无法真正分辨。从异常中,显然receiver.getReceivedMessage()返回的对象不是UserUAI类型。若此方法必须返回对象,而您无法将其更改为返回特定类型,以便防止从对象强制转换盲类型,那个么至少您可以这样做
Object received = receiver.getReceivedMessage();
if(received instanceof UserUAI)
{
UserUAI userUAI = (UserUAI) received;
}
为了防止出现异常错误。显然,receiver.getReceivedMessage()返回的对象不是UserUAI类型。若此方法必须返回对象,而您无法将其更改为返回特定类型,以便防止从对象强制转换盲类型,那个么至少您可以这样做
Object received = receiver.getReceivedMessage();
if(received instanceof UserUAI)
{
UserUAI userUAI = (UserUAI) received;
}
为了防止错误。如上所述,返回的对象类型不正确。这里有一个简单的方法来确定实际返回的对象类型。如果获得NullPointerException,则返回的对象为null
private Object o = receiver.getReceivedMessage();
System.out.println(o.getClass().getName());
如上所述,返回的对象类型不正确。这里有一个简单的方法来确定实际返回的对象类型。如果获得NullPointerException,则返回的对象为null
private Object o = receiver.getReceivedMessage();
System.out.println(o.getClass().getName());
从对其他答案的评论来看,您似乎有类加载器问题 试试这个:
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());
即使前两个输出看起来相同,如果由不同的类加载器加载,它们也是不同的类
要解决这个问题,我们需要更多关于您如何使用它的上下文。从对其他答案的评论来看,您似乎有类加载器问题 试试这个:
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());
即使前两个输出看起来相同,如果由不同的类加载器加载,它们也是不同的类
为了解决这个问题,我们需要更多关于您如何使用它的上下文。来理解§4.3.4部分
两种引用类型是相同的运行时类型,如果:
它们都是类或接口类型,由同一类加载器定义,
并且具有相同的二进制名称(§13.1),在这种情况下,它们有时被称为
相同的运行时类或相同的运行时接口
它们都是数组类型,并且它们的组件类型是相同的运行时类型(§10)
里面写着
如果T是类类型,则R必须是与T相同的类(§4.3.4),或
抛出T的子类或运行时异常
因此,由于不同的类加载器定义了相同的类,因此不能将其实例转换为其他类。引用§4.3.4部分
两种引用类型是相同的运行时类型,如果:
它们都是类或接口类型,由同一类加载器定义,
并且具有相同的二进制名称(§13.1),在这种情况下,它们有时被称为
相同的运行时类或相同的运行时接口
它们都是数组类型,并且它们的组件类型是相同的运行时类型(§10)
里面写着
如果T是类类型,则R必须是与T相同的类(§4.3.4),或
抛出T的子类或运行时异常
因此,由于相同的类已由不同的类装入器定义,因此其实例不能转换为其他类。解决方案一直摆在我面前。我使UserUAI类可序列化,并将其作为字节数组发送。在接收端,我对它进行反序列化,并将结果对象转换为UserUAI,它工作得很好
Ishtar,谢谢你的帖子,是规范文本给了我这个想法。解决方案一直摆在我面前。我使UserUAI类可序列化,并将其作为字节数组发送。在接收端,我对它进行反序列化,并重新播放