

`ArrayList`に指定した型があるオブジェクトと同じ型かどうかを確認することはできますか？  
例えば`ArrayList<ABC>` abc と`ABC`が同じ型かどうかを比較するということです。

`instanceOf`や`isAssignableFrom`というメソッドを使ってみたのですがうまくいきません。  
よろしくお願いします。


CC BY-SA 3.0
2016-04-15T14:34:36.987
24060
2016-04-21T12:15:20.680
2016-04-21T11:34:27.230
5337
15179
question
java
JAVA ArrayListのオブジェクトの種類を特定するには？


求めている処理結果が文章からは読み取れませんが、ArrayListという型とABCという型は違う型なので、instanceOfなどの処理で同じでないことを正しく評価できているように思われます。  
（ABCという型がListクラスを実装していたり、ArrayListを継承している場合は少し話が変わってきますが。。。。）

[code]

     ArrayList<ABC> list = new ArrayList<ABC>();
     if((list　inscetanceOf　ABC) == false) {
        System.out.println("違う型です。");
     }
    
[/code]


CC BY-SA 3.0
2016-04-21T03:24:30.987
24203
2016-04-21T03:53:21.453
2016-04-21T03:53:21.453
15234
15234
24060
answer


「ArrayList abc と
ABC」の比較でしたら、そもそも、ArrayListクラスとABCクラスは違うクラスなので比較するまでもありませんが、次で検証はできます。

[code]

    if (abc instanceof ABC) {
      // trueだった場合の処理
    } else {
      // それ以外
    }
    
[/code]

ArrayListの中に"格納された"オブジェクトの比較をして、ABCクラスがあるかどうかを調べたい、という質問でしたら、次のようにして比較が可能です。

[code]

    List list = new ArrayList();
    list.add(new ABC());
    list.add(new XYZ());
    
    for (Object obj:list) {
      if ( obj instanceof ABC ) {
        // ABCだった場合の処理
      } else {
        // それ以外
      }
    }
    
[/code]


CC BY-SA 3.0
2016-04-21T05:01:18.643
24207
2016-04-21T05:01:18.643
5778
24060
answer


あるオブジェクトの型`T`と、ジェネリクスに指定した型変数の型（例えば`List<T>`の`T`）が同じ型かどうかを判定したいという質問意図であると考えて回答します。

## コンパイル時

たとえば`ArrayList<String>`のように型変数を指定すると、`ArrayList`が取り扱うオブジェクトの型が`String`であることは保証されます。

ですので、コード上で`ArrayList<ABC>`と書けば、その`ArrayList`が`ABC`型にバインドされていることは自明なので、単純に任意のオブジェクトが`ABC`型であるかどうかの判定を行えばよいのではないでしょうか。

[code]

    Object object; // 実際の型か分からない謎のオブジェクトがあると仮定
    if (object instanceof ABC) { 
        // instanceof 演算子で ABC 型かどうかを判定すればよい
    }
    
[/code]

リストが要素を持っているのであれば、以下のような記述はできますが、直接的に型変数が何かを知る方法はありません。

[code]

    String object = "ABC";
    List<String> list = new ArrayList<String>();
    list.add("DEF");
    if (list.get(0).getClass().isAssignableFrom(object.getClass())) {
        System.out.println("true");
    }
    
[/code]

## 実行時

Javaのジェネリクスは型消去によって実装されています。それが`List<String>`から、直接`String`という型を知る術がない理由です。

ソースコード上では`ArrayList<ABC>`と`ArrayList<DEF>`は異なるものとして扱われますが、コンパイル時にその情報は失われて（型情報が消去されるので型消去）、両者はただの`ArrayList`とみなされます。

ですので、実行時に型変数の型を知ることはできません。

ただし上記の説明は厳密には正確ではなく、あるクラスのフィールドや、メソッドの引数がジェネリクスだった場合、例えば、

[code]

    private List<String> hoge;
    
    public void hoge(List<String> fuga) {
    
    }
    
[/code]

上記の`hoge`や`fuga`の型情報は実行時にも保持されます。

リフレクションを使って`ParameterizedType`を取得すればいいのですが、質問者の意図からは外れていると思いますので、そういうものもありますとだけ。


CC BY-SA 3.0
2016-04-21T12:15:20.680
24224
2016-04-21T12:15:20.680
5337
24060
answer