2
public class Hashing<Key, Elem>

Key が int かどうかを確認したいので、コンストラクターに次の行を配置します。

Key key = null;
if (!(key instanceof Integer)) {
    throw new TypeOfKeyStillNotSupportedException();
}

ただし、次の方法で作成します。

tHash = new Hashing<Integer, Movie>(max);

そして、いまいましい TypeOfKeyStillNotSupportedException() がポップします。なぜこれが起こっているのですか、どうすれば適切に行うことができますか?

前もって感謝します。

編集: null が割り当てられているキーに問題があることが既にわかっています。問題は次のとおりです。チェックを行う方法は?

4

6 に答える 6

3

nullは何もありませんinstanceof。型消去のため、Key実行時に型を直接確認する方法はありません。Class<Key>1 つのオプションは、次のことを確認できるように、ユーザーがコンストラクターに渡されるようにすることです。

public Hashing(Class<Key> keyType, ...) {
  if (keyType != Integer.class) {
    throw new TypeOfKeyStillNotSupportedException();
  }
  ...
}

...

Hashing<Integer, Foo> hashing = new Hashing<Integer, Foo>(Integer.class, ...);

型引数を繰り返す手間を省くために、静的ファクトリ メソッドを作成できます。

public static <K, E> Hashing<K, E> create(Class<K> keyType, ...) {
  return new Hashing<K, E>(keyType, ...);
}

...

Hashing<Integer, Foo> hashing = Hashing.create(Integer.class, ...);
于 2011-05-04T03:26:54.680 に答える
2

コードに「key = null;」がある場合 instanceof のテストの直前に、例外が必ずスローされます。

その理由は、instantcof 演算子が、それがどのように宣言されているかではなく、指されているオブジェクトの型の参照をチェックするためです。

この簡単な例を試してみて、それに応じてコメントを削除して違いを確認できます。

public static void main(String[] args) {
    //Object obj = new Integer(9);
    Object obj = null;

    if (!(obj instanceof Integer))
        System.out.println("Not Integer.");
    else
        System.out.println("Is Integer");
}

また、ここで詳細を確認できます。

http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

それが役に立てば幸い :)


Java Generics の完全な例:

class GenTest<Key extends Integer, Value>{
    Key key;
    Value val;

    GenTest(Key key, Value val){
        this.key = key;
        this.val = val;

        System.out.println("Key: " + key + " Value: " + val);
    }
}

public class GenericRecap {
    public static void main(String[] args) {
        //Object obj = new Integer(9);
        Object obj = null;

        if (!(obj instanceof Integer))
            System.out.println("Not Integer.");
        else
            System.out.println("Is Integer");

        new GenTest<Integer, String>(9, "nine");
    //new GenTest<String, String>("funny", "nine");  // In-Error
    }
}

また、'Key extends Integer' を使用すると、Integer をサブクラス化しないパスを渡すと、実行時に例外がスローされることに注意してください。さらに、それをチェックする IDE を使用している場合は、GenTest クラスの「境界内にない型」としてフラグが立てられます。

float と Integer はすべて Number から継承します。したがって、「Number を拡張」してから、コードでの使用方法に応じて「instanceof Integer」または「instanceof Float」をチェックできます。

それが役立つことを願っています:)乾杯!

于 2011-05-04T03:29:34.093 に答える
2

Javaジェネリックは、型消去を使用して実装されます。ジェネリック情報は、型チェックに使用された後、コンパイラによって破棄されるため、実行時にクラスは事実上ただHashing<Object, Object>. そのため、ジェネリック型に基づいて実行時チェックを行うことはできません。

型の引数をコンストラクターに追加できますClass<Key>。呼び出し元は、キーとして使用されている型の正しいクラス オブジェクトを渡す必要があります。たとえば、 では、その引数の値としてHashing<Integer, String>のみInteger.classが受け入れられ、それを実行時の型チェックに使用できます。ただし、キーのクラス オブジェクトをパラメーターとして渡す必要があるため、コンストラクターの呼び出しは少しぎこちなく見えます。

于 2011-05-04T03:35:35.353 に答える
0

これに対処する方法は、nullを明示的にテストすることです。例えば

Key key = null;
if (key == null) {
    throw new KeyIsNullException();
} else if (!(key instanceof Integer)) {
    throw new TypeOfKeyStillNotSupportedException();
}

// ... or (for the literal minded) ...

if (key != null && !(key instanceof Integer)) {
    throw new TypeOfKeyStillNotSupportedException();
}

記録として、これは型消去と関係があると答えた人々はベースから外れています。Key明確なクラスまたはインターフェースの 場合、まったく同じ動作が得られます。

(一方、コードがsomeObj instanceof Key...と言っていた場合、型消去の問題のためにコンパイルエラーになります。)

于 2011-05-04T03:51:30.857 に答える
0

演算子の動的等価物であるisInstanceメソッドが必要です。instanceof

例えば、

Integer.class.isInstance(1); //return true
Integer.class.isInstance(null); //return false

編集
異なるクラスタイプに対してテストする場合は、次のようなユーティリティメソッドを記述します。

static <T> boolean isInstance(Class<T> type, Object obj) {
    return type.isInstance(obj);
}

例えば、

Hashing.<String>isInstance(String.class, "hi"); // return true
于 2011-05-04T03:56:25.270 に答える
0

あなたの例から次のことを考えると:

public class Hashing<K, E>

これは意味がありませんKTypeクラスが特殊化されている場合、 は何にでも設定できるからです。を表していないという混乱を避けるために、名前を から に変更しましKeyた。名前の一般的な基準は、ほとんどの場合、1 文字を使用することです。KKeyTypeType

K key = null;
if (!(key instanceof Integer)) 
{
    throw new TypeOfKeyStillNotSupportedException();
}

に変更すると

K key = null;
if (!(key instanceof K)) 
{
    throw new TypeOfKeyStillNotSupportedException();
}

それはより多くの解決策になりますが、常にのタイプになるためGeneric、それも意味がありませんkeyK

keynullではないため、することnullはできませんType

小切手の周囲の状況を詳しく説明instanceofしないと、あなたの意図がわかりません。

Typeの aGenericをチェックするのinstanceofはコードの匂いであり、おそらく間違ったアプローチです。

java.util.HashMap 実装がこの問題をどのように処理するかをここで見てください。

それらが使用する場所は 2 つだけでありinstanceof、それらは両方とも受け入れのみObjectでタイプセーフではないレガシー メソッドです。

于 2011-05-04T03:36:43.453 に答える