0

我正在编写通用编码器/解码器并遇到扩展通用的问题。这个想法是我想要一个抽象的 Encodeable 类,它有一个“虚拟”静态方法 decode,它接受一个 Byte[] 并构造对象,类似于 Serializable。(我知道这在 java 中不能真正做到。)扩展 Encodeable 的每个类都将覆盖编码/解码方法。然后我想通用地使用这些 Encodeable 子类。这是试图说明我的意思:

public class Encodeable{

    // I'd like to write 
    // static abstract Encodeable decode(Byte[]);
    // similar to 
    // virtual Encodeable decode(Byte[]) = 0;  
    // in C++, but that seems to be illegal in java

    static Encodeable decode(Byte[] buf){return null};

}

public class EncodeableFoo extends Encodeable{

      static EncodeableFoo decode(Byte[] buf){
          // do actual decoding logic here
      }

}

public class Bar<T extends Encodeable>{

    public void messageReceived(MessageEvent e){
        Byte[] buf = e.getMessage();
        T messageObj = T.decode(buf);
        // do something with T
    }

}

照原样,我收到一条错误消息,例如

error: incompatible types
    T messageObj = T.decode(objBuf);
                           ^
  required: T
  found:    Encodeable
  where T is a type-variable:
    T extends Encodeable declared in class EdgeClientHandler

在编译时。但是如果我将解码线更改为

T messageObj = (T) T.decode(objBuf);

它工作得很好。有人可以向我解释这个黑魔法吗?或者,更重要的是,给我一个更好的方法来编写我的通用 Bar 类,这样它就知道 T 有一个静态方法解码(和一个非静态方法编码)?

4

2 回答 2

6

首先,Java 中的静态方法不能是抽象的。

其次,如果您希望编译器了解您返回的是 a T,而不仅仅是a ,则需要将该方法声明为泛型Encodeable。我建议完全远离static这里。基本思想:

public interface Decoder<T> {
    T decode(Byte[] buf);
}

public class FooDecoder implements Decoder<Foo> {
    Foo decode(Byte[] buf){
        // do actual decoding logic here
    }
}

public class Bar<T extends Encodeable> {

    private Decoder<T> decoder; // you'll have to figure out where to get this

    public void messageReceived(MessageEvent e){
        Byte[] buf = e.getMessage();
        T messageObj = decoder.decode(buf);
        // do something with T
    }
}

您的原始设置似乎混合了可编码类型和知道如何从 a 解码此类类型的东西byte[],所以我重命名并摆弄了一下。


附带问题:为什么Byte[]是 s 而不是byte[]s?

于 2013-02-15T17:15:45.227 回答
3

你的设计在我看来有点乱。我不会使用静态方法而是做这样的事情:

public interface Decoder<T extends Encodable> {
    T decode(Byte[] buf);
}

public class Bar<T extends Encodable> {
    private final Decoder<T> decoder;

    public Bar(Decoder<T> decoder) {
        this.decoder = decoder;
    }

    public void messageReceived(MessageEvent e) {
        Byte[] buf = e.getMessage();
        T messageObj = decoder.decode(buf);
        // do something with T
    }
}
于 2013-02-15T17:21:30.400 回答