2

次の機能を実装したい:

public boolean checkType(Vector<?> vec)
{
  // return true if its Vector<Integer> and false otherwise
}

ベクター要素の型を確認するにはどうすればよいですか? ベクトルが空である可能性があるため、最初の要素が「instanceof」整数か文字列かを確認できないことに注意してください...

編集:

うーん、うまくいくかどうかわからないことを考えていた

次のように checkType 関数を実装できますか:

public <T> boolean checkType(Vector<T> vec)
{
  // return true if T is Integer and false otherwise
}

T が Integer かどうかを確認することは可能ですか?!

前もって感謝します

4

4 に答える 4

4

ジェネリック型パラメーターは、型が eraseであるため、実行時に回復できません (一部の特殊なケースを除く) 。これは、実行時に と の両方Vector<Integer>Vector<String>単なるVectors であり、それらの要素が単なるObject参照であることを意味します。

個々の要素の実際のランタイムクラス(instanceof指摘したようにチェックで検出可能)のみが要素タイプの概念を作成します。そうでない場合、ベクター自体は要素タイプが何であるかわかりません。

したがって、基本的に、任意の型の空のベクトルは、他の型の空のベクトルと同じです。次のようにキャストしても安全です。

Vector<String> noStrings = (Vector<String>) new Vector<Integers>();

ただし、1 つの問題があります。空のベクターは必要な要素の型に準拠していると言えますが、このステートメントは、ベクターが empty のままである限り有効です。これを行う場合:

Vector<Integer> ints = new Vector<Integer>(); // empty
Vector<String> strings = (Vector<String>) ints; // unchecked warning, but still possibly ok
ints.add(1); // here comes trouble
String s = strings.get(1); // oh oh, ClassCastException

編集:

2 番目の質問に答えるには: いいえ、次のように書くことはできません。

public <T> boolean checkType(Vector<T> vec) {
    return T instanceof Integer; // impossible
    return T == Integer; // impossible
    return T.class == Integer.class // impossible
    return vec instanceof (Vector<Integer>); // impossible
}

ただし、入力パラメーターとしてクラス トークンを使用するメソッドを作成できます。

static <T> boolean checkElementType(Collection<?> collection, Class<T> elementType) {
    for (Object object : collection) {
        if (!elementType.isAssignableFrom(object.getClass())) {
            return false;
        }
    }
    return true;
}

そして、次のように使用できます。

List<?> list1 = Arrays.asList(1, 2, 3);
List<?> list2 = Arrays.asList(1, 2, 3, "a");
System.out.println(checkElementType(list1, Integer.class)); // true
System.out.println(checkElementType(list2, Integer.class)); // false
于 2012-09-08T12:47:55.587 に答える
2

これがまったく可能であるとあなたに言う人は誰でも間違っています。実行時に、空の Vector が か かどうかを判断する方法はありませVector<Integer>Vector<Rainbow>

それは多かれ少なかれ型消去の定義です。

于 2012-09-08T12:39:30.633 に答える
2

型消去のため、これは不可能です。

ベクトルが空でない場合でも、コレクション ライブラリは、異なる型のものを入れることに対して実際の保護を提供しません。

    Vector v = new Vector<Integer>();
    v.add("foo");
    System.out.println(v.get(0));

エラーなしで実行され、許可されるべきではない文字列値が適切に出力されます。

したがって、最初の要素の型をチェックしても、実行時にジェネリック型を決定しようとする試みは信頼できません。

独自の汎用コードでできることは、コンストラクター引数と値を保持するフィールドを追加して、実行時にコードが型を認識できるようにすることです。

この戦術をコレクション ライブラリ全体に適用するのは難しいでしょうが、次のように始めVectorます。

public class TypedVector<E> extends Vector<E> {

    private Class<E> genericClass;

    public TypedVector(Class<E> clazz) {
        super();
        this.genericClass = clazz;
    }

    // many other constructors ... but probably not all of them

    public Class<?> getGenericClass() {
        return genericClass;
    }

    @Override
    public boolean add(E e) {
        if (!(genericClass.isAssignableFrom(e.getClass())))
                throw new IllegalArgumentException("Incorrect class");
        return super.add(e);
    }

    // many other overrides for run-time type safety
}
于 2012-09-08T13:25:56.100 に答える
-2
public boolean checkType(Vector<?> vec)
{
  if(!vec.isEmpty())
  {
    if("String".equals(vec.get(0).getClass().getSimpleName()))
             return false;
    else if("Integer".equals(vec.get(0).getClass().getSimpleName()))
             return true;               
   }
}

お役に立てれば!!

于 2012-09-08T12:14:25.553 に答える