Java ClassCastException,其中两个相同的类位于不同的程序包中,并通过网络发送 [英] Java ClassCastException with two identical classes in different packages, sent over the network

查看:204
本文介绍了Java ClassCastException,其中两个相同的类位于不同的程序包中,并通过网络发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到以下问题:我的项目由两个程序包(客户端和服务器)组成,其中每个程序包都具有类Package.现在,我想通过ObjectOutputStream/ObjectInputStream通过网络发送此类,如下所示:

I'm having following problem: My project consists out of two packages (Client and Server), where each of them has the class Package. Now i want to send this class over the network via ObjectOutputStream / ObjectInputStream like this:

//Client - this is in package client
ObjectOutputStream out = new SocketOutputStream(socket.getOutputStream);
Package package = new Package();
out.writeObject(package);

//Server - this is in package server
ObjectInputStream in = new SocketInputStream(socket.getInputStream);
Object o = in.readObject();
if(o instanceof Package) ... //do something important

所以问题出在最后一行,我得到了ClassCastException.原因显然是他采用了完整的路径来确定对象的类型,因此client.Package不是server.Package.问题是我无法将客户端软件包放入服务器,反之亦然.

So the problem lies in the last line, where I get a ClassCastException. The reason is obviously that he takes full path to determine the type of the object, so client.Package is not server.Package. The Problem is that i cannot put the client package to the server or vice versa.

所以这才是真正的问题:是否可以在不从包(客户端/服务器)中导入Package类的情况下确定类的类型?还是有可能在没有类信息的情况下通过网络发送对象?


Package类如下所示:

So here is the real Question: Can i determine the type of the class without importing the Package class from the package (client / server)? Or is there a possibility to send the Object over the network without class information ?


The Package class looks as following:

public class Package implements Seriablizable {
    private static final long serialVersionUID = 5050301321863757269L;

    public String objectName;
    public Object[] parameters;
    public Class[] parameterTypes; //parameter types
}


已经感谢您的帮助:)


Already thanks for helping :)

推荐答案

在不同的程序包中声明两个具有相同名称的类时,它们是根本不同的类.这就是为什么当您尝试从一种类型转换为另一种类型时会得到异常的原因.

When you declare two classes with the same name in different packages, they are fundamentally different classes. That is why you are getting the exception when you attempt to cast from one type to the other.

问题是我无法将客户端软件包放到服务器上,反之亦然.

The problem is that i cannot put the client package to the server or vice versa.

您无法说服Java类型系统这两个类是相同的.他们是不同的.

There is no way you can convince the Java type system that the two classes are the same. They are different.

最简单的解决方案是创建第三个包,其中包含客户端和服务器端都需要的类.将一个或多个通用包放入一个JAR文件,并将其添加到客户端和服务器端的类路径中.

The simplest solution is to create a third package that contains the classes that are needed on both the client and server side. Put the common package (or packages) into a JAR file, and add it to the classpath on the client and server sides.

还有其他选择,例如:

  • 使用其他编组/解组机制(JSON,XML,自定义),或

  • using a different marshalling / unmarshalling mechanism (JSON, XML, custom), or

使用Java序列化库中的可用钩子来转换类型(请参见@EJP的答案),

using the available hooks in the Java serialization library to translate types (see @EJP's answer),

但是(请记住),这个问题归结于一个设计错误,最好的方法是很快修复该错误,而不是在其上进行书面记录.

but (to mind) this problem is down to a design mistake, and the best approach is to fix that mistake soon rather than papering over it.

如果要通过Java序列化将对象从Java客户端传递到Java服务器,则应该在两边使用相同的类.如果由于合理的技术原因(不同于设计错误)无法做到这一点,那么很可能是不使用Java序列化的一个很好的理由.

If you are passing objects from a java client to a java server via Java serialization, then you should be using the same classes on both sides. If that is not possible for a sound technical reason (as distinct from a design mistake), then that is most likely a good reason NOT to use Java serialization.

要回答您的真实"问题:

To answer your "real" questions:

问:我可以确定类的类型而不从包(客户机/服务器)中导入Package类吗?

Q: Can i determine the type of the class without importing the Package class from the package (client / server)?

完全可以,但不会帮到您.

Strictly yes, but it won't help you.

  • 您可以通过全限定名来引用类;例如

  • You can refer to a class by its fully qualified name; e.g.

if (o instanceof com.acme.WeaselTrap)

  • 您可以获取实际类型的Class对象.

    Class<?> clazz = o.getClass();
    

  • 但是一旦到达那里,仍然会遇到以下问题:在不同程序包中具有相同名称的两种类型在根本上是不同的..

    But once you have gotten there, you still have the issue that the two types with the same names in different packages are fundamentally different.

    (当然,如果您的代码可以处理不同的类,则可以通过更改类名称以使简单名称不同来简化您的生活.)

    (Of course, if your code can cope with the classes being different, you could make your life simpler by changing the class names so that the simple names are different.)

    问:或者是否有可能在没有类信息的情况下通过网络发送对象?

    Q: Or is there a possibility to send the Object over the network without class information ?

    不使用Java序列化.

    Not using Java serialization.

    这篇关于Java ClassCastException,其中两个相同的类位于不同的程序包中,并通过网络发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆