2017-09-22 1 views
2

을 사용하여 매개 변수화 된 인터페이스에서 클래스 추출 인터페이스에서 Java 8 기본 메소드를 사용하여 추상 클래스를 사용하는 대신 매개 변수화 된 유형의 클래스를 추출하려면 어떻게해야합니까?기본 메소드

옵션 1 (실패) :

public interface EpicCoolInterface<T> { 

default Class<T> getParameterizedTypeClass() { 
    return T.class; //doesn't work 
} 

옵션 2 (실패) :

public interface EpicCoolInterface<T> { 

default Class<T> getParameterizedTypeClass() { 
    return (Class<T>) ((ParameterizedType) getClass().getGenericInterfaces()[0]) 
    .getActualTypeArguments()[0]; 
    //java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
} 

세 번째 (성공하지만 인터페이스) 시도 :

public abstract class CoolAbstractClass<T> { 

    private Class<T> clazz; 

    public CoolAbstractClass() { 
    try { 
     this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) 
      .getActualTypeArguments()[0]; 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    } 

    public Class<T> getType() { 
    return clazz; 
    } 
} 

답변

1

사실, 무엇을 generic 타입 추론이 필요합니다.

세 번째 시도가 작동하지만 상황을 지정하는 데만 적용 할 수 있습니다 (클래스가 추상 클래스를 직접 확장 함).

당신은 당신이 github에 소스 코드와 자바 독을 찾을 수 있습니다 내 유틸리티 클래스 GenericUtil의 방법

Type[] getGenericTypes(Type sourceType, Class<?> targetClass) 

를 사용할 수 있습니다.

public static interface EpicCoolInterface<T> { 
    // Return Type rather than Class, because T not always be a class. 
    // You can do type check and return Class<T> with force typecast. 
    default Type getParameterizedTypeClass() { 
     return GenericUtil.getGenericTypes(getClass(), EpicCoolInterface.class)[0]; 
    } 
    } 

를 그리고 이제 우리의 코드를 테스트하자 : 귀하의 질문에 대한

,이처럼 inteerface를 정의 할 수 있습니다

public static void main(String[] args) { 
    EpicCoolInterface<Integer> a = new EpicCoolInterface<Integer>() { 
    }; 
    System.out.println(a.getParameterizedTypeClass()); 
    EpicCoolInterface<EpicCoolInterface<Integer>> b = new EpicCoolInterface<EpicCoolInterface<Integer>>() { 
    }; 
    System.out.println(b.getParameterizedTypeClass()); 
    EpicCoolInterface<EpicCoolInterface<?>> c = new EpicCoolInterface<EpicCoolInterface<?>>() { 
    }; 
    System.out.println(c.getParameterizedTypeClass()); 
    } 

그것을 출력 :

class java.lang.Integer 
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface<java.lang.Integer> 
xdean.stackoverflow.java.reflection.Q46360416.xdean.stackoverflow.java.reflection.Q46360416$EpicCoolInterface<?> 
관련 문제