是否可以在通用函数中测试类型?

时间:2011-02-24 23:15:58

标签: java generics

我想创建一个泛型函数,将字节数组反序列化为调用者指定的类型。 我觉得调用这样一个函数的一种非常直观的方式看起来像是:

byte[255] myData = [...]
String myUnserializedString = new Packet<String>(myData).unpack();

byte[4] myInt = [...]
int myUnserializedInt = new Packet<Integer>(myInt).unpack();

作为用户,这是我想要提供的那种界面。问题是(显然)每种类型都必须以不同的方式进行反序列化。这意味着unpack()方法必须执行某种反身测试,以选择正确的方式来解释原始字节。

尝试了一段时间为这样的课程编写原型后,我开始觉得Generics可能不适合进行这种设计。

是吗?

4 个答案:

答案 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