【问题标题】:Deserialize byte array into class whose name is given as String将字节数组反序列化为名称为 String 的类
【发布时间】:2018-09-26 11:51:41
【问题描述】:

我有从 java 对象序列化的数据(可以有不同类型的对象),我还有字符串格式的序列化数据类型的完全限定类名。 现在我想要一个泛型方法(非泛型已经工作),我将向其传递字符串格式的类名和字节数组数据,作为回报,它将返回反序列化的类对象。有点类似于下面的签名

public <T> T convertByteArrayToObject(String className, byte[] data);

例如,如果我通过convertByteArrayToObject("java.lang.String", [65, 66, 67]);

那么它应该返回“ABC”作为字符串对象(但自定义类型也应该适用)。

谢谢

【问题讨论】:

  • 然后你必须实现那个方法,就像你实现从任意对象创建字节数组的另一个方法一样。
  • 我认为你可以这样做public static &lt;T&gt; T convertByteArrayToObject(String className, byte[] data) throws Exception { Constructor&lt;?&gt; c = Class.forName(className).getConstructor(byte[].class); return (T) c.newInstance(data); };但是投到T 很好,没用。我不认为这是以通用方式可行的,因此您在编译时就知道您的类型;我的意思是你在运行时知道className
  • @Holger 但这仍然不可能以通用方式对吗?我的意思是 className 的类型仅在运行时才知道,我认为没有办法在编译时强制执行此操作
  • @Eugene 你可以声明一个像public &lt;T&gt; T convertByteArrayToObject(Class&lt;T&gt; expectedType, byte[] data) 这样的方法,但不清楚方法中的魔法应该如何工作。如果我事先知道预期的类型(在编译时),我可以写,例如new String(byteArray) 首先。并不是说建议使用默认字符集……
  • @Holger 好吧,OP 直到运行时才知道该类,我想这就是它通过 className 的原因,还不知道 Class&lt;T&gt; 并且魔法可能只是触发构造函数,如果有的话

标签: generics java-8 deserialization


【解决方案1】:

想一想,你想要一个泛型方法 - 这样它就可以在编译时强制执行某种类型安全,但你在运行时只有 className;这根本不可能,或者您并不真正了解问题。你可以假装它是通用的,例如:

public static <T> T convertByteArrayToObject(String className, byte[] data) throws Exception {
    Class<?> clazz = Class.forName(className);
    Constructor<?> c = clazz.getConstructor(byte[].class);
    return (T) c.newInstance(data);
}

但是这种转换是没有用的,你的方法真的只返回Object,所以你可以在调用者中将它分配给你想要的任何东西:

Integer s = convertByteArrayToObject("java.lang.String", new byte[] { 65, 6, 67 });

所以这个编译得很好,给你一个类型安全的假印象。另一方面,调用者在运行时会失败;因为在它们的字节码中有checkcast 调用。坚持你所拥有的一切并进行适当的检查。

【讨论】:

  • 嗨,我明白你的意思了。但是,如果 T/className 的所有可能值都肯定实现 Serializable 接口,这会有所不同吗?
  • @Jayesh 很遗憾没有,你可以声明 &lt;T extends Serializable&gt; 并在删除后是 Serializable,但这对你没有多大帮助
  • 谢谢@Eugene,我理解你在这里试图解释的概念。所以我所做的是我创建了一个自定义标记接口,并且我想要反序列化的所有类都必须实现这个接口。所以现在我知道,在编译时,它需要反序列化到哪个类。然后我使用instanceof检查类型转换为正确的类。这对我有用。
猜你喜欢
  • 1970-01-01
  • 2010-10-05
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
相关资源
最近更新 更多