13

このコードを考えると:

List<Integer> ints = new ArrayList<Integer>();

// Type mismatch: 
// cannot convert from Class<capture#1-of ? extends List> to Class<List<Integer>>       
Class<List<Integer>> typeTry1 = ints.getClass(); 

// Type safety: 
// Unchecked cast from Class<capture#2-of ? extends List> to Class<List<Integer>>
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();

// List is a raw type. References to generic type List<E> should be parameterized
Class<? extends List> typeTry3 = ints.getClass(); 

エラーや警告なしClassで aを取得する方法はありますか? List<Integer>警告を簡単に抑制することができますが、Java がこの有効なコードに対して警告を抑制する必要がある場合、私は非常に失望します。

一方、警告の抑制が唯一の方法である場合、抑制するのが最も安全な方法は何ですか?

4

2 に答える 2

6

これは Java での実際の Catch-22 です。

ジェネリック型を に追加しないと、コンパイラは警告しますList

// WARN: List is not typed
Class<? extends List> typeTry3 = ints.getClass();

これは、ほとんどの場合、リストを入力するのが本当に最善であるためです。

ただし、型消去のため、Java がList実行時にジェネリック型を把握する方法はなく、コンパイラはそれを認識しています。したがって、Class型付きオブジェクトを返すメソッドはありません。

// ERROR: ints.getClass() doesn't return a Class<List<Integer>>, it returns a Class<List>
Class<? extends List<? extends Integer>> var = ints.getClass();

したがって、型付きリストにキャストする必要があります。ただし、ご存知のように、実行時の型チェックがないため、Java は型付き変数へのキャストについて警告します。

// WARN: Casting to typed List
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();

これを回避しようとする試みは、本質的にコンパイラを混乱させる手段であり、必然的に複雑になります。

その場合の最善の策は、オプション B を使用することです。

一方、警告の抑制が唯一の方法である場合、抑制するのが最も安全な方法は何ですか?

この警告を抑制する最も安全な方法は、@SuppressWarnings("unchecked")注釈を可能な限りローカライズすることです。それらを個々のチェックされていないキャストの上に置きます。そうすれば、誰が警告を発しているのかが完全に明確になります。

于 2012-06-16T05:00:06.430 に答える
4

これを行う 1 つの方法は、独自のクラスを作成することです。これがあなたのニーズを満たすかどうかはわかりません。

あなたが何を達成しようとしているのか、私にはよくわかりません。したがって、おそらくワイルドカードが答えです。

import java.util.*;

class Main
{
      public static void main(String[] args)
      {
            List<Integer> list = new ArrayList<Integer>();
            Class<?> clazz = list.getClass();
            System.out.println(clazz) ;
      }
}
于 2012-06-16T04:02:34.773 に答える