0

昨日この投稿を見ました: How I instantiate? コードを含める

ユーザーは、ジェネリック クラスのコンストラクター型 X を、コンストラクター IA に渡されるオブジェクトの型と一致させることができませんでしたが、<X extends IA>.

XM コンストラクターの型を からに変更する必要がある場合、ジェネリックの全体のポイントが役に立たなくなるため、提供された唯一の答えが本当に好きではありませんでしたIA<X>M確かにこれがジェネリック型が<X extends IA>??である理由です。

この基本的な例で (抑制された警告なしで) ジェネリックを使用する方法は本当にありませんか?

public interface IA<X extends IA<X>>{}

public class A<X extends IA<X>> implements IA<X>{}

public class W<X extends IA<X>>{}

public class M<X extends IA<X>> extends W<X>{
    X anx;

    public M(X x){} //Type X here is not compatibile with IA in the test code
}


//Testing code in a different class
public <X extends IA<X>> void check() {

    IA<X> a = new A<X>();
    W<X> s = new M<X>(a); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA> 
    W<X> s = new M(a);    //Compiles, but with suppressed warnings

    X a = new A<X>();  //Doesnt compiler (ignoring dupicate 'a' variable)  
    W<X> s = new M<X>(a); compiles
}

「拡張」を含むあらゆる場所にIAを含めるように編集

4

3 に答える 3

2

次のようなことをしなければなりません:

//Testing code in a different class
public <X extends IA<X>> void check() {
    IA<X> a = new A<X>();
    W<subtypeofIA(IA works as well)> s = new M<subtypeofIA(IA works as well)>(a); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA> 
    W<X> s = new M(a);    //Compiles, but with suppressed warnings 
}

警告に関しては、一目瞭然であり、次のように要約できると思います。使用したいときにジェネリックにパラメーター化された型がある場合、ジェネリックパラメーターを具象型にインスタンス化する必要があります。コードを一般化するだけでなく、型の安全性を強化するために、ジェネリック パラメーターが導入されました。IA を使用するということは、IA < ASpecificType > と言って得られたタイプ セーフを破棄することを意味し、コンパイラはこれに注意を向けます。

次のコードは、私があなたのコードに最も近いものであると同時に、意味をなすものです。

interface IA<X extends IA<X>>{}

class A<X extends IA<X>> implements IA<X>{}

class W<X extends IA<X>>{}

class M<X extends IA<X>> extends W<X>{
    X anx;

    public M(X x){} //Type X here is not compatibile with IA in the test code 
}


//Testing code in a different class
public <X extends IA<X>> void check() {

    IA<X> a = new A<X>();
    W<X> s = new M<X>(null); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA> 
    W<X> ss = new M(a);    //Compiles, but with suppressed warnings

    X aa = new A<X>();  //this is completely illegal  
    W<X> sss = new M<X>(aa); //compiles
}
于 2012-07-13T12:56:11.797 に答える
1

この質問には、意味をなさない多くの一般的な制約が含まれています。のコンストラクターは、ジェネリック メソッドの型パラメーターであるM<X>type の引数を受け取ります(つまり、呼び出し元は任意のものを決定でき、これは引き続き機能する必要があります)。では、なぜ(またはそれに関する他の何か) が適切なタイプであると期待するのでしょうか?XcheckXa

ジェネリックの制約を変更して機能させる方法を知りたい場合は、コンパイルするはるかに単純なものを次に示します (ジェネリックを変更するだけで (ただし、元のものはそのまま保持WMます)、他には何もありません)。とにかく欲しかった:

public interface IA<X>{}

public class A implements IA<A>{}

public class W<X extends IA<X>>{}

public class M<X extends IA<X>> extends W<X>{
    X anx;

    public M(X x){}
}


public void check() {

    A a = new A();
    W<A> s = new M<A>(a);
}
于 2012-07-13T19:52:38.797 に答える
0

問題は、コンストラクターに渡される a がタイプ IA であることです。M のコンストラクターには X が必要です。IA は X にキャストできないため、これは構文エラーです。

2 番目のオプションはコンパイルされますが、実際に実行すると、実際には X のインスタンスではない変数に amx を割り当てることになります (したがって、これは悪い考えであるという警告が表示されます)。

IA を取り込むようにコンストラクターを変更すると、すべてうまくいきます。

于 2012-07-13T13:06:43.310 に答える