我想创建一个泛型函数,将字节数组反序列化为调用者指定的类型。 我觉得调用这样一个函数的一种非常直观的方式看起来像是:
byte[255] myData = [...]
String myUnserializedString = new Packet<String>(myData).unpack();
byte[4] myInt = [...]
int myUnserializedInt = new Packet<Integer>(myInt).unpack();
作为用户,这是我想要提供的那种界面。问题是(显然)每种类型都必须以不同的方式进行反序列化。这意味着unpack()方法必须执行某种反身测试,以选择正确的方式来解释原始字节。
尝试了一段时间为这样的课程编写原型后,我开始觉得Generics可能不适合进行这种设计。
是吗?
答案 0 :(得分:3)
您可以将Packet定义为接口,并为每种类型的数据设置一个实现。
public interface Packet<T> {
T unpack(byte[] data);
}
public final class StringPacket implements Packet<String> {
public String unpack(byte[] data) {
// Implementation...
}
}
// Similar classes for other types...
答案 1 :(得分:1)
仿制药在这里没有提供任何真正的类型安全性,但它可以提供一些铸造方便性。但是,显而易见的方法是让unpack方法完成所有工作:
public <T> T unpack(Class<T> klass) {
return klass.cast(unpackedData);
}
并称之为:
new Packet(myData).unpack(String.class);
即使您可以将泛型转换为按照您想要的方式完成(我认为您可以使用不安全的演员,无论如何都是Class.cast),这是更标准的idom并且避免您自己做不安全的铸造。无论哪种方式,您都说客户端知道类型,因为它在您的示例中设置了Generic参数。
答案 2 :(得分:1)
如果他们必须以不同的方式处理,那么Packet不是真正的通用!
没有错
class StringPacket extends Packet {
// ...
}
或
class StringPacket implements Receivable, Sendable {
// ...
}
答案 3 :(得分:0)
为什么不呢?
class Packet<T> {
private byte[] bytes;
// consructor here
public T unpack() {
(T) readObject(bytes);
}
}
readObject(..)
可以依赖ObjectInputStream