java泛型扩展类型错误

and*_*dge 0 java generics types

我正在编写一个通用的编码器/解码器,并遇到了扩展通用的问题.我的想法是,我希望有一个抽象的Encodeable类,它具有一个"虚拟"静态方法解码,它接受一个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
    }

}
Run Code Online (Sandbox Code Playgroud)

按原样,我收到一条错误消息

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
Run Code Online (Sandbox Code Playgroud)

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

T messageObj = (T) T.decode(objBuf);
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*all 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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


旁边的问题:为什么Byte[]s而不是byte[]s?

  • 哈哈 - 得出了相同的结论;-) (2认同)