1

ジェネリックを使用して単純なインターフェイスを構築しようとしています。使用しようとしているコードは次のとおりです。

public interface MyInterface<T>
{
   public ArrayList<T> items;
   //...
}

ただし、非静的コンテキストから静的変数 T にアクセスするなどのエラーが発生します。どうすればやろうとしていることを達成できますか? これは、このインターフェイスを実装するクラスの使用を想定する方法です。

MyInterface<SomeObject> foo = new MyInterfaceImpl<>();

for (SomeObject bar: foo.items)
{
     bar.someMethod();
}

これはインターフェイス経由で指定できますか?

4

5 に答える 5

3

インターフェイスで宣言されたすべての変数は、デフォルトで static および final であるため、ジェネリック型 T は適用できませんArrayList。そのため、エラーが促進されます非静的型 T への静的参照を作成できません

Java言語仕様セクションから。8.1.2

  • 次の場所でジェネリック クラス C の型パラメーターを参照すると、コンパイル エラーになります。
  • C の静的メンバーの宣言 (§8.3.1.1、§8.4.3.2、§8.5.1)、または
  • C 内にネストされた任意の型宣言の静的メンバーの宣言、または
  • C の静的初期化子 (§8.7)、または
  • C 内にネストされた任意のクラス宣言の静的初期化子。
于 2013-02-13T08:17:37.190 に答える
2

主な問題は、インターフェイスで宣言されたときにデフォルトで静的であるデータ メンバーです。

静的データ メンバーは、ジェネリック パラメーターを参照できません。異なるインスタンスは異なる型引数を持つことを許可されるべきですが、静的メンバーはそれらすべてで共有されているため、特定の型引数にリンクすることはできません。

于 2013-02-13T08:23:35.953 に答える
1

Eyalの説明に従って、次のようにします。

public interface MyInterface<T> {
  Collection<T> getItems();
}

クラスを実装すると、動的データメンバーが保持されます。

public class MyImpl<T> implements MyInterface<T> {
  private Collection<T> items;
  public Collection<T> getItems() { return items; }
}
于 2013-02-13T08:29:27.003 に答える
1

基本的に、インターフェースは機能 (クラスができること) を記述し、実装 (インスタンスがそれらの機能を実現する方法) を記述しません。

この他のstackoverflowの質問から

Java インターフェースはそれ自体ではインスタンス化できないため、インターフェース変数は静的です。変数の値は、インスタンスが存在しない静的コンテキストで割り当てる必要があります。final 修飾子は、インターフェイス変数に割り当てられた値が、プログラム コードによって再割り当てできない真の定数であることを保証します。

ここで実際に必要なのは、抽象基本クラスです

class abstract Base<T> implements MyInterface<T> {
    //btw it's recommended that you use interfaces as the declaring type not implementations
    public List<T> items = new ArrayList<T>;
}

class MyInterfaceImpl<T> extends Base<T> {
   //...
}

抽象基本クラスには、public/protect/private インスタンス フィールドを含む 0 ~ 100% の実装を含めることができるという利点があります。

于 2013-02-13T08:25:34.193 に答える
0

あなたはこれをしなければなりません:

MyInterface<SomeObject> foo = new MyInterfaceImpl<SomeObject>();

for (SomeObject bar: foo.items)
{
    bar.someMethod();
}

MyInterfaceImplは、ジェネリックである場合、またはジェネリックでない場合は適切なクラスでパラメーター化する必要があることに注意してください。括弧は必要ありません。

于 2013-02-13T08:15:44.110 に答える