2

2 つの異なるインターフェイスを実装するクラスのインスタンスを保持する属性を宣言したいと思います。私はこの構文を試しました:

private <? extends Interface1 & Interface2> name;

この:

private <T extends Interface1 & Interface2> T name;

それらのどれも機能しません。出来ますか?構文は何ですか?Interface1と の両方から継承する別のインターフェイスを宣言しないようにしていますInterface2


編集:

この属性を含むクラスには、型引数を指定しないでください。それはこのようなものではありません:

public class MyClass<T extends Interface1 & Interface2>{
    private T name;
    ...
}

クラスを使用している人にとっては意味がありません。そのクラスがジェネリックであることは、論理的にも不可能でもありません。

4

4 に答える 4

4

これは、次のようにクラス宣言に含める必要があります。

public class TestG<T extends Cloneable & Serializable> {
    private T name;
}

1つの代替手段は、メソッドで設定することです(ただし、変数ではありません)

public class TestG {
    public <T extends Cloneable & Serializable> void  method(T parameter) {
    }
}
于 2012-11-17T10:09:26.053 に答える
2

変数をジェネリックにすることはできません。

private <T> T var;

は不可能です - どの時点でT定義されていますか? にアクセスするときvar、割り当て時に何を使用したかについてあまり推測できません。

Java では、クラスおよびメソッドでジェネリックを使用できます。だからあなたが持つことができます

private <T implements Cloneable & Serializable> void setVar(T val);

クラス全体の type を持つことができますT

しかし、最終的には型 erase によって実装されることを常に覚えておいてください。ゲッター、セッター、キャストを使用して、より複雑なロジックをいつでもエミュレートできます。適切に行うと、型の安全性が同じになります。

必要な型安全性を持つ変数を取得する最も簡単な方法は、2 つの変数とセッターを使用してそれらを同期させることです。

private Serializable vars;
private Cloneable vars;

もちろん、優れた型安全性を提供します。ただし、4 バイトの追加メモリとセッターが必要です。

あなたが尋ねたキャスティングアプローチは次のとおりです。

private Object internal_var;

// Implementation notice: do not remove this generic.
// Due to a Java limitation, we *do* want these two constraints!
public <T extends Serializable & Cloneable> void setVar(T val) {
    internal_var = val;
}

public Serializable getSerializable() {
    return (Serializable) internal_var; // Type checked in setter!
}

public Cloneable getCloneable() {
    return (Cloneable) internal_var; // Type checked in setter!
}

// This is the way to use it in a generic getter:
public <T extends Serializable & Cloneable> T getVar(Class<? super T> cls) {
    return (T) cls.cast(val);
}

Tgetter で使用するには、T を含むパラメーターが必要であることに注意してください。 class を知っていると仮定するとExample implements Serializable, Cloneableを使用できます。

// This actually ensures we get an instance of `Example` out:
Example e = instance.getVar(Example.class);
于 2012-11-17T10:23:17.910 に答える
2

その型パラメータをclass declaration、 またはmethod declarationの場合はで宣言しlocal variable、代わりにその型を使用できます。

public class Demo<T extends Interface1 & Interface2> {
    private T t;
} 

また: -

public class Demo {
    public <S extends Interface1 & Interface2> void demo(S param1) {
        S param;
    }
}
于 2012-11-17T10:10:12.793 に答える
1

私があなたの質問を正しく理解していれば、両方の inetrfaces を実装するジェネリック クラスが必要です。クラス定義でジェネリック型引数を宣言し、それをインスタンス変数型として作成します。

public class Implementor<T extends Interface1<T> & Interface2<T>>  {
    private T t;

}

編集:

のようにインスタンス変数宣言で型引数を宣言することはできません

 private <T extends I1 &I2> T t; //this cant be achieved. 

ただし、メソッド レベルでは可能です。

public <T extends I1 & I2> void method(T t){

  }
于 2012-11-17T10:08:37.133 に答える