[java] 리턴하기 위해 오브젝트를 일반 유형으로 캐스트

메소드의 값을 리턴하기 위해 오브젝트를 캐스트하는 방법이 있습니까? 이 방법을 시도했지만 “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바이트 코드 명령이 기본 방법에 일어나는되지 convertInstanceOfObjectconvertInstanceOfObject방법은 던질 수있는 모든 명령이 없습니다 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”은 예외없이 콘솔에 인쇄됩니다.convertInstanceOfObjectClass.cast()ClassCastExceptioncatch(ClassCastException e)null


답변

예외 던지기에 의존하지 않으려면 (아마도 안됩니다) 다음을 시도하십시오.

public static <T> T cast(Object o, Class<T> clazz) {
    return clazz.isInstance(o) ? clazz.cast(o) : null;
}


답변