java - 有没有办法发送可序列化类的不同子类的实例?
问题描述
我已经构建了一个客户端-服务器应用程序,具有工作连接设置和处理。我希望客户端发送不同类型的请求,每个请求都有唯一的字段,但所有这些都继承自“请求”超类。有没有办法做到这一点?
例如,我有一个实现可序列化的 Foo 类
class Foo implements Serializable{
public String name;
public Foo() {
this.name = "Default";
}
public Foo(String name) {
this.name = name;
}
}
以及扩展它的两个子类
class BarOne extends Foo {
public String name;
public int id;
public Bar(String name, int id) {
super(name);
this.id = id;
}
}
class BarTwo extends Foo {
public String name;
public String lastName;
public Bar(String name, String lastName) {
super(name);
this.lastName = lastName;
}
}
有没有办法让客户端通过 ObjectOutputStream 发送 BarOne 和 BarTwo 的实例,并让服务器确定它接收到的是一个实例还是另一个实例?
解决方案
这里没有限制,你可以毫无困难地序列化一个子类。
在这里,我提供了一个使用与您相同的结构的快速示例(但带有特定示例)。
抽象类。
public abstract class Pojo implements Serializable {
private static final long serialVersionUID = -4947411931465651278L;
protected int id;
public Pojo() {
// TODO Auto-generated constructor stub
}
public Pojo(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
第一个子类Person
class Person extends Pojo {
private static final long serialVersionUID = -7814628079202659483L;
private String name;
private int age;
public Person(int id, String name, int age) {
super(id);
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
}
}
第二个子类Address
class Address extends Pojo {
private static final long serialVersionUID = -8266402026827561883L;
private String address;
private String city;
public Address(int id, String address, String city) {
super(id);
this.address = address;
this.city = city;
}
@Override
public String toString() {
return "Address [address=" + address + ", city=" + city + ", id=" + id
+ "]";
}
}
然后,您可以为此示例创建一个集合,该集合将包含两种类型的实例:
List<Pojo> pojos = new ArrayList<>();
pojos.add(new Address(1, "Address 1", "city1"));
pojos.add(new Address(2, "Address 2", "city2"));
pojos.add(new Person(1, "Name1", 5));
pojos.add(new Person(2, "Name2", 10));
pojos.add(new Person(3, "Name3", 15));
您可以使用文件进行序列化(因为我没有时间创建套接字系统;))使用:
private static void serialize(String filename, Serializable data)
throws IOException {
try (OutputStream outStream = new FileOutputStream(filename);
ObjectOutputStream fileObjectOut = new ObjectOutputStream(
outStream)) {
fileObjectOut.writeObject(data);
}
}
private static Object deserialize(String filename) throws IOException,
ClassNotFoundException {
try (InputStream inStream = new FileInputStream(filename);
ObjectInputStream fileObjectIn = new ObjectInputStream(inStream)) {
return fileObjectIn.readObject();
}
}
让序列化和反序列化列表以查看类型是否恢复:
serialize("data.ser", pojos);
List<Pojo> tmp = deserialize("data.ser");
System.out.println(tmp);
您将看到具有正确实例类型的结果:
[
Address [address=Address 1, city=city1, id=1],
Address [address=Address 2, city=city2, id=2],
Person [name=Name1, age=5, id=1], Person [name=Name2, age=10, id=2],
Person [name=Name3, age=15, id=3]
]
所以你可以对任何东西做同样的事情,只序列化 a Person
,你需要恢复第Object
一个并使用 aninstanceof
来查看恢复的类型。
Pojo p1 = new Person(1, "Name1", 10);
serialize("person.ser", p1);
Object o1 = deserialize("person.ser");
System.out.println(o1);
System.out.println(o1.getClass());
System.out.println(o1 instanceof Person);
输出
Person [name=Name1, age=10, id=1]
class serial.Person
true
推荐阅读
- python - Django 是否为模板使用内置变量名?
- ruby-on-rails - 模型中表的未知主键 (ActiveRecord)
- java - 如果没有依赖注入,Java Spring 中的 XML IoC 有什么意义?
- functional-programming - 如何从方案中的函数返回值
- javascript - 对象作为 React 子级无效。如果您打算渲染一组子项,请改用数组 - 错误 Solidity - React
- php - 如何使用 PHP 解析网页内的图像?
- reactjs - Gatsby 中的 Prismic 插件出现“无效插件选项”错误
- laravel - 如何根据登录用户隐藏按钮?在HTML
- xpath - 为什么带有 XPATH 的 IMPORTXML 除了返回预期结果之外还返回意外的空白行?
- html - CSS未使用引导程序加载