programing

반환을 위해 개체를 일반 유형으로 캐스팅

goodsources 2022. 8. 10. 22:25
반응형

반환을 위해 개체를 일반 유형으로 캐스팅

메서드의 값을 반환하기 위해 객체를 캐스팅하는 방법이 있습니까?이렇게 시도했지만 "instance of" 부분에서 컴파일 시간 예외가 발생했습니다.

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인스턴스(instance)는 컴파일 중 일반 유형 삭제로 인해 발생합니다.

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왜냐하면 메인 메서드에서는 다음 명령어를 잡을 수 없기 때문입니다.ClassCastException따라서 당신이 주요 방법을 실행할 때 당신은 얻을 수 있습니다.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; 따라서 예외 없이 콘솔에 "displicate"가 인쇄됩니다.

예외 발생에 의존하고 싶지 않은 경우(대부분 그렇지 않은 경우) 다음과 같이 시도해 볼 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/14524751/cast-object-to-generic-type-for-returning

반응형

'programing' 카테고리의 다른 글

Vue-test-utils 래퍼가 정의되지 않았습니다.  (0) 2022.08.10
코딩 규칙 - 명명 규칙  (0) 2022.08.10
C: loop int 초기 선언용  (0) 2022.08.10
C/C++ 회선 번호  (0) 2022.08.10
int vs 플로어에 캐스팅  (0) 2022.08.10