Java Generics : 반환 유형으로 만 정의 된 Generic 유형
GWT에 대한 GXT 코드를 살펴보고 있으며 Java 자습서에서 다른 예를 찾을 수없는 Generics를 사용했습니다. 클래스 이름은 com.extjs.gxt.ui.client.data.BaseModelData
모든 코드를보고 싶은 경우입니다. 다음은 중요한 부분입니다.
private RpcMap map;
public <X> X get(String property) {
if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) {
return (X)NestedModelUtil.getNestedValue(this, property);
}
return map == null ? null : (X) map.get(property);
}
X
클래스의 다른 곳이나 계층의 어디에도 정의되어 있지 않으며, 이클립스에서 "선언으로 이동" <X>
을 누르면 공용 메서드 서명으로 이동합니다.
다음 두 가지 예를 사용하여이 메서드를 호출하여 어떤 일이 발생하는지 확인했습니다.
public Date getExpiredate() {
return get("expiredate");
}
public String getSubject() {
return get("subject");
}
컴파일하고 오류나 경고를 표시하지 않습니다. 나는 이것이 작동하도록 적어도 나는 캐스트를해야한다고 생각할 것입니다.
이것은 Generics가 무엇이든 될 수있는 매직 리턴 값을 허용하고 런타임에 폭발 할 것이라는 것을 의미합니까? 이것은 제네릭이해야 할 일과 반대되는 것 같습니다. 누구든지 이것을 나에게 설명하고 아마도 이것을 좀 더 잘 설명하는 문서에 대한 링크를 줄 수 있습니까? 제네릭에 대한 Sun의 23 페이지 pdf를 살펴 보았고 반환 값의 모든 예는 클래스 수준에서 정의되거나 전달 된 매개 변수 중 하나에 있습니다.
이 메서드는 예상되는 모든 유형을 반환합니다 ( <X>
메서드에 정의되어 있으며 절대적으로 제한되지 않음).
반환 유형이 실제로 반환 된 값과 일치한다는 규정이 없기 때문에 매우 위험합니다.
이것이 갖는 유일한 장점은 모든 유형을 반환 할 수있는 이러한 일반 조회 메서드의 반환 값을 캐스팅 할 필요가 없다는 것입니다.
나는 말하고 싶다 : 당신은 거의 모든 유형 안전성을 잃고 .NET을 호출 할 때마다 명시 적으로 캐스트를 작성할 필요가 없다는 것만 얻을 수 있기 때문에 신중하게 그러한 구조를 사용하십시오 get()
.
그리고 예 : 이것은 거의 런타임에 폭발하고 제네릭이 달성해야하는 전체 아이디어를 깨뜨리는 흑 마법입니다.
형식은 메서드에서 선언됩니다. 그것이 " <X>
"의 의미입니다. 유형은 메소드로만 범위가 지정되고 특정 호출과 관련됩니다. 테스트 코드가 컴파일되는 이유는 컴파일러가 유형을 결정하려고 시도하고 불가능한 경우에만 불평하기 때문입니다. 명시 적이어야하는 경우가 있습니다.
예를 들어에 대한 선언 Collections.emptySet()
은 다음과 같습니다.
public static final <T> Set<T> emptySet()
이 경우 컴파일러는 다음을 추측 할 수 있습니다.
Set<String> s = Collections.emptySet();
그러나 할 수없는 경우 다음을 입력해야합니다.
Collections.<String>emptySet();
나는 GXT 수업에서 똑같은 것을 알아 내려고했다. 특히 다음 서명을 사용하여 메서드를 호출하려고했습니다.
class Model {
public <X> X get(String property) { ... }
}
코드에서 위의 메서드를 호출하고 X를 문자열로 캐스트하려면 다음을 수행합니다.
public String myMethod(Data data) {
Model model = new Model(data);
return model.<String>get("status");
}
위의 코드는 get 메서드를 호출하고 X에서 반환하는 형식을 문자열로 반환해야한다고 알려줍니다.
메서드가 여러분과 같은 클래스에있는 경우 "this."로 호출해야한다는 것을 알았습니다. 예를 들면 :
this.<String>get("status");
다른 사람들이 말했듯이 이것은 GXT 팀에 의해 다소 조잡하고 위험합니다.
BaseModelData는 안전하지 않기 때문에 컴파일 될 때 확인되지 않은 경고를 발생시킵니다. 이와 같이 사용하면 코드 자체에 경고가 없더라도 런타임에 ClassCastException이 발생합니다.
public String getExpireDate() {
return get("expiredate");
}
RpcMap (GXT API 1.2)의 흥미로운 메모
get의 헤더 :
public java.lang.Object get(java.lang.Object key)
Having a generic parameter of <X>
in there that's uninstantiated has the same effect, except you don't have to say "Object" all over the place. I agree with the other poster, this is sloppy and a bit dangerous.
Yes, this is dangerous. Normally, you'd protect this code like so:
<X> getProperty(String name, Class<X> clazz) {
X foo = (X) whatever(name);
assert clazz.isAssignableFrom(foo);
return foo;
}
String getString(String name) {
return getProperty(name, String.class);
}
int getInt(String name) {
return getProperty(name, Integer.class);
}
참고URL : https://stackoverflow.com/questions/338887/java-generics-generic-type-defined-as-return-type-only
'Development Tip' 카테고리의 다른 글
iOS 9 Safari : 스크롤하는 동안 요소를 고정 위치로 변경하면 스크롤이 멈출 때까지 페인트되지 않습니다. (0) | 2020.11.11 |
---|---|
Keras에게 손실 값을 기반으로 훈련을 중지하도록 알리는 방법은 무엇입니까? (0) | 2020.11.11 |
케이스 당 여러 값으로 PHP 전환을 수행하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.11 |
부분 렌더링 : 객체 대 : 지역 (0) | 2020.11.11 |
Play 프레임 워크에서 선택적 쿼리 매개 변수를 처리하는 방법 (0) | 2020.11.11 |