메소드의 값을 리턴하기 위해 오브젝트를 캐스트하는 방법이 있습니까? 이 방법을 시도했지만 “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가에 발생하는 이유를 설명하기 위해 JVM 바이트 코드 수준에서 찾은 결과를 제공한다고 생각했습니다 ClassCastException
.
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 메소드를 실행할 때 catch하지 않기 때문에 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
메소드 에 bock에 의해 잡히고 리턴 되는 메소드를 호출 하는 invokevirtual
명령 이 있음을 주목하십시오 . 따라서 “null”은 예외없이 콘솔에 인쇄됩니다.convertInstanceOfObject
Class.cast()
ClassCastException
catch(ClassCastException e)
null
답변
예외 던지기에 의존하지 않으려면 (아마도 안됩니다) 다음을 시도하십시오.
public static <T> T cast(Object o, Class<T> clazz) {
return clazz.isInstance(o) ? clazz.cast(o) : null;
}