Java:XからYへの未チェックキャスト / Castornullの実装方法
-
30-09-2019 - |
質問
私はこの関数を実装しました:
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に存在するのだろうか?
私がそれを使用したい1つの例:
void removeEmptyRawStrings() {
for(Iterator<Entity> e = entities.iterator(); e.hasNext();) {
RawString s = castOrNull(e.next());
if(s != null && s.content.isEmpty()) e.remove();
}
}
私のコードには、このようなケースがかなり頻繁にあります。そして、これは他の何よりも読みやすく、よりシンプルだと思います。しかし、そのコードをさらに簡単にする方法については、より良い提案をしてください。
解決
したがって、ここでの問題は、一般的なパラメーターです 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;
}
}
他のヒント
期待どおりに機能するかどうかは完全にはわかりません。 (もちろん何を期待するかに依存します:-)しかし、このコードはたとえば、 java.lang.ClassCastException
(IDEONE):
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が得た 「正しい」ソリューション.
この方法で警告を抑制することができます。 @SuppressWarnings("unchecked")
このコードがまったく機能しないJava Genericsのおかげで。ジェネリックは、クラスが実行時に汎用型情報を使用しないため、時間型チェックをコンパイルするのにのみ役立ちます。
あなたのコードはこれにコンパイルされます:
static Object castOrNull(Object obj) {
try {
return (Object)obj;//FAIL: this wont do anything
}
catch(ClassCastException e) {
return null;
}
}
CAST to Objectは決して失敗しません。コンパイルされたコードは、コンパイル時に存在する汎用タイプにアクセスできません。キャストは、未チェックの操作のための警告を受け取るべき方法では起こらないので。