템플릿 유형 템플릿이 리턴 값 (Java) 인 경우
-
19-09-2019 - |
문제
리턴이 템플릿으로 설정되면 템플릿 변수의 데이터 유형이 무엇인지 궁금했습니다. 나는 이것을 어딘가에 코드로 보았지만 세션에서 검색된 값을 어디에 시전하는지 모르겠습니다.
public class RequestObject {
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
}
이 외부의 코드는 다음과 같습니다.
MyClassType type = request.getFromSessionMap("abc");
라인은 내 객체에 캐스팅 할 때 ClassCastException을 만난다. 그러나 section.getAttribute ( "ABC")에 추가하면 유형이 MyClasstype임을 보여줍니다. 모든 도움이 감사하겠습니다.
분명히 템플릿을 사용하기위한이 특수 코드는 getfromsessionmap을 변수 유형으로 반환하므로 캐스트가 필요하지 않습니다. 이것은 모든 경우에 작동하지만 갑자기 코드의 한 부분에서 실패했습니다.
해결책
분명히 템플릿을 사용하기위한이 특수 코드는 getfromsessionmap을 변수 유형으로 반환하므로 캐스트가 필요하지 않습니다.
기본적으로, 거기 이어야한다 결과를 얻는 것 사이의 어딘가에 타입 캐스트 session.getAttribute(sessionKey)
그리고 과제 MyClassType
. 자바 언어 (및 JVM) 허용하지 않습니다 A가 아닌 일부 대상 MyClassType
인스턴스 (또는 하위 유형)가 MyClassType
변하기 쉬운.
코드를 어떻게 작성하든 타입 캐스트가 발생해야합니다. 그리고 속성 (명백히)은 MyClassType
(또는 하위 유형), 당신은 a ClassCastException
.
실제 질문은 왜 컴파일 오류를받지 않습니까? 그리고 대답은 @SuppressWarnings("unchecked")
! 해당 경고를 제거하면이 행에 "안전하지 않은 유형 변환"오류 메시지가 표시됩니다.
return (T) session.getAttribute(sessionKey);
사실, Java는 (실제) 유형을 일반 유형으로 수행 할 수 없습니다. 그것이 바로 경고 / 오류 메시지가 지적 할 것입니다. 실제로 코드가 컴파일되면이 코드는
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
실제로 이것과 의미가 다르지 않습니다.
public Object getFromSessionMap(String sessionKey) {
return session.getAttribute(sessionKey);
}
기술적으로 말하면 이것을 "유형 삭제"라고합니다.
그렇다면 유형 확인 / typecast는 실제로 어디에서 발생합니까? 답은이 줄에 있습니다.
MyClassType type = request.getFromSessionMap("abc");
여기에 TypEcast를 작성하지는 않았지만 Java 컴파일러가 생성 한 코드는 값을 할당하기 전에 TypeCast를 수행합니다. type
. 해야합니다. 아는 한, 그것이 할당하는 인스턴스는 어느 객체 유형.
다른 포스터는 클래스 인수를 추가 할 것을 제안했습니다 getFromSessionMap
. 그 자체로 이것은 그렇습니다 절대적으로 아무것도 없습니다. 방법의 본문을 다음과 같이 바꾸는 경우
return clazz.cast(session.getAttribute(sessionKey));
방법이 실제로 실제 유형 확인을 수행하게됩니다. 그러나 이것은 유일한 원인입니다 ClassCastException
다른 장소에 던져지기 위해. 그리고 과제 진술 여전히 숨겨진 유형 캐스트를 할 것입니다 !!
다른 팁
질문의 예에서 반환 유형은 T
. 지워진 유형이 될 것입니다 Object
암시 적으로, T extends Object
. 실제 캐스트는 호출 방법의 바이트 코드에서 수행됩니다 (사용할 수 있습니다. javap -c
그것을 보려면).
일반적으로 세션에서 "최상위"객체의 수를 최대한 작게 유지해야합니다. 그렇게하는 이점 중 하나는 더 이상 이와 같은 해킹 방법이 필요하지 않다는 것입니다.
내 코드가 ClassCastException을 만나기 때문에 모든 도움이 감사하겠습니다.
당신이 받고 있다면 ClassCastException
, 그것은 당신이 다음 코드에서와 같이 무언가에 무언가를 던지려고한다는 것을 의미합니다.
Map session = new HashMap();
session.put("date", "2009-11-12");
Date today = (Date) session.get("date"); // tries to convert String to Date
그만큼 ClassCastException
"java.lang.string은 java.util.date에 캐스트 할 수 없습니다"와 같은 깨달음 세부 메시지가 있어야합니다.
메소드 본문 내에서 주조 된 유형을 사용합니다 ('(t) 세션 .getAttribute (sessionkey)').
그것은 당신이 컴파일러에게 명시 적으로 말한다는 것을 의미합니다 '반환 된 객체가 T이고 오류가 발생하지 않으면 오류를 처리 할 준비가되어 있다고 확신합니다.'.
속성 유형에 대한 귀하의 가정이 잘못되었고 오류가 발생했습니다. 따라서 모든 것이 정확하고 런타임은 이미 그렇지 않은 실제 속성 객체 유형을 제공합니다. IS-A MyClasstype.