web-dev-qa-db-ja.com

パラメーター化された型ArrayList <Foo>に対してinstanceofチェックを実行できません

次のコード:

((tempVar instanceof ArrayList<Foo>) ? tempVar : null);

原因:

パラメーター化された型ArrayList<Foo>に対してinstanceofチェックを実行できません。実行時にさらに一般的な型情報が消去されるため、代わりにArrayList<?>の形式を使用します

「実行時にさらに一般的な型情報が消去される」とはどういう意味ですか?これを修正する方法はありますか?

51
Caner

つまり、パラメーター化されたものがある場合、たとえばList<Foo> fooList = new ArrayList<Foo>();、ジェネリック情報は実行時に消去されます。代わりに、これはJVMがList fooList = new ArrayList();を見るものです。

これは type erasure と呼ばれます。 JVMには、実行時のList(この例では)のパラメーター化された型情報はありません。

修正? JVMには実行時にパラメータ化された型の情報がないため、instanceof of ArrayList<Foo>を実行する方法はありません。パラメータ化された型を明示的に「保存」して、そこで比較を行うことができます。

52
Buhake Sindi

代わりに常にこれを行うことができます

try
{
    if(obj instanceof ArrayList<?>)
    {
        if(((ArrayList<?>)obj).get(0) instanceof MyObject)
        {
            // do stuff
        }
    }
}
catch(NullPointerException e)
{
    e.printStackTrace();
}
26
Greg

型の消去により、ArrayListのパラメーター化された型は実行時に認識されません。 instanceofでできる最善の方法は、tempVarが(何でも)ArrayListであるかどうかを確認することです。ジェネリックフレンドリーな方法でこれを行うには、次を使用します。

((tempVar instanceof ArrayList<?>) ? tempVar : null);
10
Paul Bellora

これで十分です。

if(obj instanceof ArrayList<?>)
{
   if(((ArrayList<?>)obj).get(0) instanceof MyObject)
   {
       // do stuff
   }
}

実際、instanceofは、左のオペランドがnullであるかどうかを確認し、実際にfalseである場合はnullを返します。
そのため、NullPointerExceptionをキャッチする必要はありません。

2
StøcciD

それを修正することはできません。 Genericsの型情報は実行時に利用できず、アクセスできません。配列の内容のみを確認できます。

1
flob

instanceof演算子は実行時に機能します。ただし、Javaは、実行時にパラメータ化された型情報を保持しません。コンパイル時に消去されます。したがって、エラーが発生します。

1
deeKay

使用できます

boolean isInstanceArrayList = tempVar.getClass() == ArrayList.class
0
Devishankar

これはいつでもできる

クラスを作成する

public class ListFoo {
  private List<Foo> theList;

  public ListFoo(List<Foo> theList {
    this.theList = theLista;
  }

  public List<Foo> getList() {
    return theList;
  }
}

同じではありませんが...

myList = new ArrayList<Foo>;
.....
Object tempVar = new ListFoo(myList);
....
((tempVar instanceof ListFoo) ? tempVar.getList() : null);
0
jmfm