0

ジェネリック エンコーダー/デコーダーを作成していて、拡張されたジェネリックで問題が発生しています。アイデアは、Serializable と同様に、Byte[] を取り、オブジェクトを構築する「仮想」静的メソッド デコードを持つ抽象 Encodeable クラスが必要だということです。(これは実際には Java では実行できないことはわかっています。) Encodeable を拡張する各クラスは、encode/decode メソッドを上書きします。次に、これらの 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);

それはうまく動作します。誰かこの黒魔術を説明してくれませんか? または、もっと重要なことに、T が静的メソッド デコード (および非静的メソッド エンコード) を持っていることを認識できるように、ジェネリック Bar クラスを記述するより良い方法を教えてください。

4

2 に答える 2

6

まず、Java の静的メソッドは抽象化できません。

第 2 に、 .Tだけでなく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 に答える