2012-08-06 4 views
1
public static <T> T inCache(T obj) throws ClassNotFoundException { 
     String[] token = validateCookie(); //gives me to strings 
     if (token == null) 
      return null; 
     if (Cache.get(token[0]) != null) { 
      if (Cache.get(token[0]).getClass() == Class.forName(token[1]) 
        && obj.getClass() == Cache.get(token[0]).getClass()) { 
       T test = (T) Cache.get(token[0]); 
       return test; 
      } 
     } 
     return null; 
    } 

위의 코드는 완전히 잘못된 것입니다.자바 반사/제네릭

Basicly 나는 이런 식으로 뭔가를 할 :

  • 내가 내 함수에서 클래스를 설정합니다. 예를 들어, 난 내 캐시에서 얻을 목적은 내가 이전에 지정한 같은 클래스가있는 경우 inCache<User>();
  • 확인하시기 바랍니다. 클래스가 일치하는 경우 (obj.getClass == User.class)

  • 는 클래스에 객체를 캐스팅하고 돌아갑니다. return (User)obj

이렇게 사용하고 싶습니다. 클래스 서명으로

User user = inCache<User>(); 

답변

6

, 왜이 같은 것을 사용하지 않는 : 다음

public static <T> T inCache(Class<T> clazz) throws ClassNotFoundException { 
    ... 
} 

과 같이 호출 :

이 가
User user = inCache(User.class); 

제네릭을 사용할 수 없습니다 런타임에 형식 지움으로 인해 설명한 (User user = inCache<User>();) 방식, 즉 T의 유형은 런타임에 알 수 없습니다.

또한, 예를 들어, 그것뿐만 아니라 서브 클래스를 확인 할 수 Class#isAssignableFrom(...)를 사용하여 테스트하기 위해 더 좋을 수도 있습니다 clazz.isAssignableFrom(Cache.get(token[0]).getClass()). 그렇게하면 인터페이스 또는 수퍼 클래스를 전달할 수 있으며 객체가 하위 유형 인 경우 여전히 일치 항목을 얻을 수 있습니다.

+0

+1. 조금 정교하게. . . 'T test = (T) ...'대신'T test = clazz.cast (...)'라고 쓰면된다. ([http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#cast(java.lang.Object)](http://docs.oracle.com/javase)를 참조하십시오. /7/docs/api/java/lang/Class.html#cast%28java.lang.Object%29).) – ruakh

+0

@ruakh 'T'에 캐스팅하는 것이 좋을 것입니다. 안 그래야합니까? – Thomas

+0

대단히 감사합니다 :). 이게 내 문제를 해결했습니다 –