关于 socket 序列化的疑惑

174 天前
 gomorebug

某天老师布置的实验需要用到 socket 编程,在网上看到可以序列化对象,于是尝试的的去使用。 现在有个问题,我传入的对象是 User 对象如下:

public class User implements Serializable {
    @Serial
    private static final long serialVersionUID = 6L;
    //其他成员变量
}

服务端的包为 Server ,客户端的包为 Client 。两者都有 pojo.User ,User 类的结构一致。 在服务端中用 Object inputObject = inputStream.readObject()读取:

Socket clientSocket = serverSocket.accept();
ObjectInputStream inputStream = new ObjectInputStream(clientSocket.getInputStream());
Object inputObject = inputStream.readObject();
System.out.println(inputObject);
if (inputObject instanceof User) {
    User receivedUser = (User) inputObject;
    System.out.println(receivedUser);
}

但问题来了,无论如何程序无法进入 if 语句内,inputObject instanceof User 返回的结果都为 false ,在 idea 中调试发现 inputObject.getClass().getName()读取的结果确实是 User ,但 instanceof 返回的结果是 false 。 进一步调试发现当我采用 Server.pojo.User 创建对象时,Server 中的 inputObject instanceof User 就能正确返回 true 了,但采用 Client.pojo.User 创建时,就返回了 false 。

为了方便各位 V 友看,情况是这样:

万能的 V 友们,这个是怎么回事/(ㄒoㄒ)/~~

1173 次点击
所在节点    Java
10 条回复
nulIptr
174 天前
Server.pojo.User 和 Client.pojo.User 当然不是一个类型啊,名字都不一样,你这只是两个类型离字段是相同的,不要用编程语言提供的序列化功能,可以发 json 或者 msgpack 等等的东西,只要字段一样就能反序列化
pocketz
174 天前
你已经把答案说出来了。。。
liangkang1436
174 天前
一般会把 user 类放到一个 public 包里面,然后客户端和服务端都依赖这个包
pocketz
174 天前
你再确认一下 getClass().getName() 是不是只返回了 User ,理论上包名也是返回值一部分
gomorebug
174 天前
有报名我发帖的时候忽略了()
gomorebug
174 天前
@liangkang1436 但这样不符合 client 和 server 的关系好像
gomorebug
174 天前
@nulIptr 搜嘎
cpstar
174 天前
6# 啥叫不符合 S 和 C 的关系,S 和 C 用的都是同样一个 User ,放在两个 package 里边才叫不符合关系,S 和 C 只是位置概念,并不是 entity 关系概念。或者你换个想法,世界上本没有 S 或者 C ,都是干活,所谓的 C 干收集的活,所谓的 S 干处理的活,收集和处理都是同样一个东西,你说该不该是同样一个 User ?

从语言层面,instanceof User 到底是 server.User 还是 client.User ,看你 import 的是什么,server.User 和 client.User 是完全两个类。序列化除了序列化类的数据内容,还有很多类加载的相关信息,把 server.User 序列化再反序列化,还是 server.User ,当然不是 client.User 的 instance 。所以 2#说的一点都没错,你自己就把答案说出来了。
gomorebug
174 天前
@cpstar 受教了
orangie
174 天前
java 一个类的完整名称其实是包+类名,应该用 getCanonicalName()获得这个标准名称而不是 getName()。更深入一点还涉及每个类的类加载器也限定了这个类。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/993272

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX