0

次のコードがあります。

class MyClass<T>{
    public void method(){
        List<T>= new ArrayList<T>();
    }
}

次の理由は正しいですか?非静的メソッドから型パラメーターArrayList<T>であるをインスタンス化しようとしています。の特定のインスタンスで必要です。インスタンス化の場合、コンパイラは型を明示的に認識している必要があります。私が理解したように、コンパイラは非静的コンテキストで型パラメーターを既知としてマークするため、インスタンス化できます。TmethodMyClass<T>MyClass<T>TTArrayList<T>

しかし、次のコードを書くと:

class MyClass<T>{
    public void method(){
        List<T>= new ArrayList<T>();
        new T();// Compile Error
    }
}

コンパイル エラーが発生しました。抽象ファクトリ パターンを適用したり、そのニーズにリフレクションを使用したりできることはわかっています。ただし、new演​​算子には特定の型が必要です。型パラメータTは非静的コンテキストに固有です。どこで私は間違った推論をしましたか?

4

2 に答える 2

3

私が理解しているように、コンパイラは既知の非静的コンテキストで型パラメータ T をマークしているため、ArrayList をインスタンス化できます。

いいえ。静的でないコンテキストでも、コンパイラは型が何を意味するかを知りませんT。機能する理由new ArrayList<T>();は、コンパイラーがArrayList<E>0-arg コンストラクターを持っていることを知っているためです。型パラメーターTは、実際の型引数に置き換えられます。そして、それはどんなタイプでもありえます。そして、任意のタイプの を作成できるので、ArrayListそれで問題ありません。

ただし、新しい演算子には特定の型が必要です。型パラメータ T は非静的コンテキストに固有です。どこで私は間違った推論をしましたか?

の場合new T();、コンパイラは型Tがわからないため、アクセス可能な 0-arg コンストラクターがあるかどうかもわかりませTん。以下のようなクラスを考えてみましょう:

class Test {
    private int value;
    public Test(int value) { this.value = value; }
}

次に、ジェネリック クラスを次のようにインスタンス化します。

MyClass<Test> obj = new MyClass<Test>();

ここで、コンパイラが を許可すると仮定するとnew T();、このインスタンス化では、 - を実行するようなものになりますnew Test();。しかし、 には 0 引数のコンストラクターはありませんTest。では、そのコードが実行時にどのように動作すると予想しますか? それは確かに例外をスローします。これは、コンパイラがコンパイラ エラーを表示することによって防止するものです。

Tbound - を指定することで、型パラメーターにさらに情報を追加できますT extends Number。しかし、それでは型パラメーターのメソッドにしかアクセスできません。コンストラクターにはまだアクセスできません。

于 2013-09-29T09:40:35.363 に答える
2

コンパイラは、クラス T (実行時に存在しない) が引数のないコンストラクターを持つことをどのように知るのでしょうか? これを保証する方法がないため、明らかに許可されるべきではありません。

于 2013-09-29T09:39:05.540 に答える