オブジェクトをキャストしてメソッドの値を返す方法はありますか?私はこの方法を試しましたが、「instanceof」部分でコンパイル時の例外が発生しました:
public static <T> T convertInstanceOfObject(Object o) {
if (o instanceof T) {
return (T) o;
} else {
return null;
}
}
私もこれを試してみましたが、実行時例外ClassCastExceptionが発生しました。
public static <T> T convertInstanceOfObject(Object o) {
try {
T rv = (T)o;
return rv;
} catch(Java.lang.ClassCastException e) {
return null;
}
}
これを簡単に行う方法はありますか?
String s = convertInstanceOfObject("string");
System.out.println(s); // should print "string"
Integer i = convertInstanceOfObject(4);
System.out.println(i); // should print "4"
String k = convertInstanceOfObject(345435.34);
System.out.println(k); // should print "null"
編集:正解の作業コピーを書きました:
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
public static void main(String args[]) {
String s = convertInstanceOfObject("string", String.class);
System.out.println(s);
Integer i = convertInstanceOfObject(4, Integer.class);
System.out.println(i);
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
コンパイル中にジェネリック型が消去されるため、Class
インスタンスを使用する必要があります。
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}
そのメソッド の宣言は次のとおりです。
public T cast(Object o)
これは配列型にも使用できます。次のようになります。
final Class<int[]> intArrayType = int[].class;
final Object someObject = new int[]{1,2,3};
final int[] instance = convertInstanceOfObject(someObject, intArrayType);
someObject
をconvertToInstanceOfObject
に渡すと、コンパイル時のタイプはObject
になります。
私はこの質問に出くわし、それが私の興味をひいた。受け入れられた答えは完全に正しいですが、OPバイトがClassCastException
に遭遇する理由を説明するために、JVMバイトコードレベルで調査結果を提供すると思いました。
私はOPのコードとほとんど同じコードを持っています:
public static <T> T convertInstanceOfObject(Object o) {
try {
return (T) o;
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34);
System.out.println(k);
}
対応するバイトコードは次のとおりです。
public static <T> T convertInstanceOfObject(Java.lang.Object);
Code:
0: aload_0
1: areturn
2: astore_1
3: aconst_null
4: areturn
Exception table:
from to target type
0 1 2 Class Java/lang/ClassCastException
public static void main(Java.lang.String[]);
Code:
0: ldc2_w #3 // double 345435.34d
3: invokestatic #5 // Method Java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: invokestatic #6 // Method convertInstanceOfObject:(Ljava/lang/Object;)Ljava/lang/Object;
9: checkcast #7 // class Java/lang/String
12: astore_1
13: getstatic #8 // Field Java/lang/System.out:Ljava/io/PrintStream;
16: aload_1
17: invokevirtual #9 // Method Java/io/PrintStream.println:(Ljava/lang/String;)V
20: return
checkcast
バイトコード命令は、convertInstanceOfObject
およびconvertInstanceOfObject
メソッドにClassCastException
をスローできる命令がないのではなく、メインメソッドで発生することに注意してください。 mainメソッドはClassCastException
をキャッチしないため、mainメソッドを実行するとClassCastException
を取得しますが、null
の出力は期待できません。
次に、受け入れられた答えにコードを変更します。
public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch (ClassCastException e) {
return null;
}
}
public static void main(String[] args) {
String k = convertInstanceOfObject(345435.34, String.class);
System.out.println(k);
}
対応するバイトコードは次のとおりです。
public static <T> T convertInstanceOfObject(Java.lang.Object, Java.lang.Class<T>);
Code:
0: aload_1
1: aload_0
2: invokevirtual #2 // Method Java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
5: areturn
6: astore_2
7: aconst_null
8: areturn
Exception table:
from to target type
0 5 6 Class Java/lang/ClassCastException
public static void main(Java.lang.String[]);
Code:
0: ldc2_w #4 // double 345435.34d
3: invokestatic #6 // Method Java/lang/Double.valueOf:(D)Ljava/lang/Double;
6: ldc #7 // class Java/lang/String
8: invokestatic #8 // Method convertInstanceOfObject:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
11: checkcast #7 // class Java/lang/String
14: astore_1
15: getstatic #9 // Field Java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: invokevirtual #10 // Method Java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
invokevirtual
メソッドにconvertInstanceOfObject
命令があり、Class.cast()
メソッドを呼び出してClassCastException
をスローします。これはcatch(ClassCastException e)
ブロックでキャッチされ、null
を返します。したがって、「null」は例外なくコンソールに出力されます。
例外のスローに依存したくない場合(おそらくそうすべきではありません)、これを試すことができます:
public static <T> T cast(Object o, Class<T> clazz) {
return clazz.isInstance(o) ? clazz.cast(o) : null;
}