6

私はこの関数を実装しました:

 static <X,Y> Y castOrNull(X obj) {
  try {
   return (Y)obj;
  }
  catch(ClassCastException e) {
   return null;
  }
 }

これにより、コンパイラに警告が表示されます。

Type safety: Unchecked cast from X to Y

正確にはわかりません。私try/catchがここでやっているのはそれをチェックしていませんか?警告を無視できますか?

私の機能は期待どおりに機能しますか?どうすれば正しく実装できますか?

私もチェックを試しましたobj instanceof Yが、Javaがジェネリックを処理する方法のために機能しません。

ところで、この関数は私には非常に便利なようです(他のコードをよりクリーンにするため)。そのような関数はすでにJavaに存在しているのではないでしょうか。


私がそれを使いたい一例:

    void removeEmptyRawStrings() {
        for(Iterator<Entity> e = entities.iterator(); e.hasNext();) {
            RawString s = castOrNull(e.next());
            if(s != null && s.content.isEmpty()) e.remove();
        }
    }

私のコードでは、このようなケースが頻繁に発生します。そして、これは他の何よりも読みやすく、単純だと思います。しかし、そのコードをさらに単純にする方法について何かあれば、私にもっと良い提案をしてください。

4

4 に答える 4

11

したがって、ここでの問題は、動的キャストに使用される場合のジェネリック パラメータYが として扱われることObjectです。CCE をスローすることはありません。静的タイプ セーフが壊れているため、呼び出し元のメソッドで CCE がスローされます。

ここでもXまったく無意味です:

ほぼ確実に正しい解決策は、このようなことを試みないことです。null悪い。キャスティングが悪い。

ただし、ナンセンスを書くことに決めた場合は、Classオブジェクトを渡すことができます。

public static <T> T evilMethod(Class<T> clazz, Object obj) {
    try {
        return clazz.cast(obj);
    } catch (ClassCastException exc) {
        return null;
    }
}
于 2010-10-14T13:50:45.763 に答える
4

期待どおりに機能するかどうかは完全にはわかりません。(もちろん、あなたが何を期待するかによって異なります:-)しかし、このコードは例えばjava.lang.ClassCastExceptionideone)になります:

public class Main {

    public static void main(String[] args) {
        Integer o = Main.<String, Integer>castOrNull("hello");
    }


    public static <X, Y> Y castOrNull(X obj) {
        try {
            return (Y) obj;
        } catch (ClassCastException e) {
            return null;
        }
    }
}

@Tom Hawtin は「正しい」解決策を得ました。

于 2010-10-14T13:31:08.263 に答える
1

このコードを設計したJavaジェネリックがまったく機能しない方法のおかげです。クラスは実行時にジェネリック型情報を使用しないため、ジェネリックはコンパイル時の型チェックにのみ役立ちます。

コードは次のようにコンパイルされます。

 static Object castOrNull(Object obj) {
  try {
   return (Object)obj;//FAIL: this wont do anything
  }
  catch(ClassCastException e) {
   return null;
  }
 }

Objectへのキャストが失敗することはなく、コンパイルされたコードは、コンパイル時に存在するジェネリック型にアクセスできません。キャストは、チェックされていない操作に対する警告を受け取るはずの方法では発生しないためです。

于 2010-10-14T14:02:57.523 に答える
1

注釈を付けることで問題がないことが確実にわかっている場合は、このメソッドで警告を抑制することができます@SuppressWarnings("unchecked")

于 2010-10-14T13:31:03.343 に答える