ProgramingTip

리터럴을 만드는 방법 : 클래스

bestdevel 2020. 12. 25. 10:29
반응형

리터럴을 만드는 방법 : 클래스>


다음을 수행하십시오.

public Class<List<String>> getObjectType() {
    // what can I return here?
}

제네릭을 만족하고 사용할 수있는 방법에서 어떤 클래스를 사용할 수 있습니까? List.class실패하지 않습니다 List.<String>class.

당신이 궁금해하는 경우 "왜"나는 봄의 구현 쓰고 있어요 FactoryBean<List<String>>구현하기 위해 나를 필요 Class<List<String>> getObjectType(). 그러나 이것은 봄 질문 아닙니다 .

편집 : SpringSource에있는 힘에 의해 내 평범한 외침이 들렸던 Spring 3.0.1은 반환 유형이로 getObjectType()변경되어 Class<?>문제를 깔끔하게 피할 수 있습니다.


이처럼 필요한 항목에 캐스팅합니다.

return (Class<List<String>>) new ArrayList<String>().getClass();

또는

return (Class<List<String>>) Collections.<String>emptyList().getClass();

그러나 나는 그것이 당신이 생각하는 것이 아니라고 생각합니다. 경고와 함께 잘 작동하지만 정확히 "아름답다"는 아닙니다.

방금 찾았어요

와일드 카드 매개 변수화 된 유형에 대한 클래스 리터럴이없는 이유는 무엇입니까?

와일드 카드 매개 변수화 된 유형에는 런타임 유형 표현이 있기 때문입니다.

따라서 캐스팅이 유일한 방법입니다.


구문을 사용 Class<List<String>>합니다. 말도 안됩니다. Java에서 경고를 생성해야합니다. 클래스 인스턴스는 항상 원시 유형을 사용합니다 Class<List>; 그게 다야. 만약 당신이 사용하는 것과 같은 표현할 수있는 제네릭의 표현할 수있는 List<String>Guice가 사용하는 것과 같은 "수퍼 타입 ​​토큰"이 필요합니다 :

http://google-guice.googlecode.com/git/javadoc/com/google/inject/TypeLiteral.html


a의 존재 Class<List<String>>는 본질적으로 위험합니다. 그 이유는 다음과 가변적입니다.

// This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}


약간의 지역을 제공하는 springframework.org 에서이 링크찾았 습니다 .

List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();

다음과 같이 해당 메소드를 구현할 수 있습니다.

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}

SUN 포럼 에서이 토론을 확인하십시오.

http://forums.sun.com/thread.jspa?threadID=5253007

그리고 "수퍼 유형 토큰"을 사용하여 해결 방법을 설명하는 참조 된 블로그 게시물 :

http://gafter.blogspot.com/2006/12/super-type-tokens.html


클래스 리터럴이 Class.forName(...)사용되는 경우 항상 사용하기 쉽습니다 .


잘 모르겠지만 다음 질문이 귀하와 관련이있을 수 있습니다.

Java 제네릭 유형 매개 변수 및 해당 유형에 대한 작업


이것에 대해 :

public class TestMain {
    public static void main(String[] args) throws Exception {
        Type type = TestMain.class.getMethod("dummy").getGenericReturnType();
        System.out.println("type = " + type);
    }

    public List<Integer> dummy() {return null;}
}

이 다음을 인쇄합니다.

type = java.util.List<java.lang.Integer>

다음 접근 방식은 문제가 있습니다.

> public Class<List<String>> getModelType() {
>   return (Class<List<String>>) new ArrayList<String>().getClass();
> }

예를 들어 수업이 유형을 말하는지 여부를 테스트하려는 경우

org.eclipse.emf.common.util.BasicEList<String> 

유형입니다

List<String> 

앞서 언급 한 getModelType () 접근 방식의 결과를 기반으로합니다.

BasicEList<String> fromObject = ...;
if (getModelType().isAssignableFrom(fromObject.getClass())) {
    transferFromModelToUi(getModelType().cast(fromObject));
}

두 객체 모두 인터페이스 List를 구현하기 때문에 false가되지만 true 여야합니다 (getModelType ()이 ArrayList가 아닌 List 유형의 Class 객체를 반환하기 때문에).

다음은 나를 위해 일한 접근 방식입니다 (조금 번거롭지 만 위의 예제에서 올바른 결과로 이어지고 정적 초기화 프로그램으로 이동할 수 있음).

public Class<List<String>> getModelType() {
    Class<?> arrayListClass = new ArrayList<String>().getClass();
    Class<?>[] interfaces = arrayListClass.getInterfaces();
    int index = 0;
    for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(List.class)) {
            index = i;
            break;
        }
    }
    return (Class<List<String>>) interfaces[index];
}

참조 URL : https://stackoverflow.com/questions/2012306/how-to-create-a-class-literal-of-a-known-type-classliststring

반응형