java.lang.ClassCastException 使用 readObject() 接收对象时
java.lang.ClassCastException when receiving object with readObject()
我在客户端有一个 bean class,用于存储用户输入数据并通过套接字将其发送到服务器。服务器具有相同的 bean class。
服务器接收到对象,但是当我尝试将接收到的对象分配给 bean class 的实例时,它会导致以下错误:
java.lang.ClassCastException: ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client
Class 错误:
public class DriveableImpl implements Driveable{
private Client client;
private ObjectOutputStream out;
private ObjectInputStream in;
public DriveableImpl() {
client = new Client();
}
// Method that receives connection socket and open in/out streams for current session
@Override
public void connect(Socket socket){
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean login() throws Exception {
// Program crash here
client = (Client) in.readObject();
System.out.println(client.toString());
return false;
}
}
我使用 InvocationHandler 来调用上面 class 中实现的方法:
public class MethodInvoker implements InvocationHandler{
private Object returnObject = null; // object that will hold any returns from invoked methods
private final Driveable userInterface;
protected MethodInvoker(Driveable ui) {
this.userInterface = ui;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException{
System.out.println("BEFORE");
returnObject = method.invoke(userInterface, args);
System.out.println(method.getName());
System.out.println("AFTER");
return returnObject; // could problem be possibly here?
}
}
我真的不确定这里发生了什么,因为它适用于客户端-服务器应用程序的简单设计。
在我看来,我正在 post 编写与错误相关的程序部分,但如果出现任何请求,我将修改 post。
谢谢!
注意序列化错误:
它清楚地表明你有 2 个不同的 classes(也许它们看起来完全一样)但它们在不同的包中:
ie.gmit.sw.**client**.methods
ie.gmit.sw.**server**.methods
这意味着,从Java的角度来看,它们完全无关
ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client
这就是你有 class 转换异常的原因
在Java中,Same Class意味着它驻留在同一个包中并且具有相同的名称。所以你应该在服务器和客户端中有相同的class。
有两种方法可以实现:
只需将相同的 class 放置两次 - 一次在客户端,一次在服务器。在您的情况下,这意味着 - 将包重命名为常见的东西。这是一个糟糕的方法,因为代码重复
将要通过序列化的对象放入第三个 "common" 模块(jar 将从中生成),当您 运行 客户端和服务器生成它们时依赖于这个模块。所以实际上你只有一份 class "Client".
我在客户端有一个 bean class,用于存储用户输入数据并通过套接字将其发送到服务器。服务器具有相同的 bean class。
服务器接收到对象,但是当我尝试将接收到的对象分配给 bean class 的实例时,它会导致以下错误:
java.lang.ClassCastException: ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client
Class 错误:
public class DriveableImpl implements Driveable{
private Client client;
private ObjectOutputStream out;
private ObjectInputStream in;
public DriveableImpl() {
client = new Client();
}
// Method that receives connection socket and open in/out streams for current session
@Override
public void connect(Socket socket){
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean login() throws Exception {
// Program crash here
client = (Client) in.readObject();
System.out.println(client.toString());
return false;
}
}
我使用 InvocationHandler 来调用上面 class 中实现的方法:
public class MethodInvoker implements InvocationHandler{
private Object returnObject = null; // object that will hold any returns from invoked methods
private final Driveable userInterface;
protected MethodInvoker(Driveable ui) {
this.userInterface = ui;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException{
System.out.println("BEFORE");
returnObject = method.invoke(userInterface, args);
System.out.println(method.getName());
System.out.println("AFTER");
return returnObject; // could problem be possibly here?
}
}
我真的不确定这里发生了什么,因为它适用于客户端-服务器应用程序的简单设计。 在我看来,我正在 post 编写与错误相关的程序部分,但如果出现任何请求,我将修改 post。
谢谢!
注意序列化错误:
它清楚地表明你有 2 个不同的 classes(也许它们看起来完全一样)但它们在不同的包中:
ie.gmit.sw.**client**.methods
ie.gmit.sw.**server**.methods
这意味着,从Java的角度来看,它们完全无关
ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client
这就是你有 class 转换异常的原因
在Java中,Same Class意味着它驻留在同一个包中并且具有相同的名称。所以你应该在服务器和客户端中有相同的class。 有两种方法可以实现:
只需将相同的 class 放置两次 - 一次在客户端,一次在服务器。在您的情况下,这意味着 - 将包重命名为常见的东西。这是一个糟糕的方法,因为代码重复
将要通过序列化的对象放入第三个 "common" 模块(jar 将从中生成),当您 运行 客户端和服务器生成它们时依赖于这个模块。所以实际上你只有一份 class "Client".