일반 삭제
우리 모두 알고 있듯이 Java의 제네릭은 런타임 시에만 유효합니다. 즉, List
이 구현 메커니즘을 선택하는 이유는 무엇입니까? 그냥 지울 수는 없나요? 제가 C++ 템플릿과 유사한 개념, 즉 제네릭을 구현하고 싶었던 것은 Java가 탄생한 지 10년 후였습니다. Java의 클래스 라이브러리는 Java 생태계에서 매우 귀중한 자산입니다. 이전 버전과의 호환성(즉, 기존 코드와 클래스 파일이 여전히 합법적임)과 마이그레이션 호환성(일반화된 코드와 일반화되지 않은 코드가 서로 호출할 수 있음)을 보장해야 합니다. 위의 두 가지 배경과 고려 사항으로 인해 Java 디자이너는 "유형 삭제"라는 절충적인 구현 방법을 채택했습니다.
동시에 런타임 중에 특정 유형의 일반 매개변수를 마음대로 가져오는 것을 방지하는 "구멍" 메커니즘이 있습니다.
TypeToken
을 사용해 본 학생들은 모두 다음과 같이 역직렬화할 때 TypeToken 유형을 정의해야 한다는 것을 알고 있습니다.
private Type type = new TypeToken<List<Map<String, Foo>>>(){}.getType(); //调用fromJson方法时把type传过去,如果type的类型和json保持一致,则可以反序列化出来 gson.fromJson(json, type);
세 가지 질문
1. ? 위에서 언급한 것처럼 List
2. 중괄호 {}가 있는 이유는 무엇인가요? 이 버팀대가 핵심입니다. 우리 모두 알고 있듯이 Java 구문에서 이 컨텍스트에서 {}는 익명 클래스를 정의하는 데 사용됩니다. 이 익명 클래스는 TypeToken의 하위 클래스인 TypeToken 클래스를 상속합니다.
3. 왜 서브클래스를 통해 일반 유형을 얻어야 하나요? 이것이 TypeToken이 일반 유형을 얻을 수 있는 핵심입니다. 이것은 영리한 방법입니다. 아이디어는 다음과 같습니다. List
내 하위 클래스가 상속해야 하는 상위 클래스의 제네릭이 결정되었습니다. 당연히 JVM은 이 정보 부분을 하위 클래스의 클래스 정보에 저장합니다.
그럼 이 정보는 어떻게 얻을 수 있나요? 다행스럽게도 Java는 다음과 같은 API를 제공합니다.
Type mySuperClass = foo.getClass().getGenericSuperclass(); Type type = ((ParameterizedType)mySuperClass).getActualTypeArguments()[0]; System.out.println(type);
요약하면 제네릭이 있는 클래스의 경우 ParameterizedType 개체가 반환되고, 개체, 인터페이스 및 기본 유형의 경우 null이 반환되고, 배열 클래스의 경우 Object.class가 반환됩니다. ParameterizedType은 JDK1.5에 제네릭이 도입된 후 Type 인터페이스를 구현하는 Java 유형입니다.
직접 디버깅하면 결과가 무엇인지 알 수 있습니다.
Principle
핵심 방법은 방금 언급한 두 문장이고, 나머지는 매우 간단합니다. TypeToken
public final Type getType() { //直接返回type return type; }
typeToken
//注意这里用了protected关键字,限制了只有子类才能访问 protected TypeToken() { this.type = getSuperclassTypeParameter(getClass()); this.rawType = (Class<? super T>) $Gson$Types.getRawType(type); this.hashCode = type.hashCode(); } //getSuperclassTypeParameter方法 //这几句就是上面的说到 static Type getSuperclassTypeParameter(Class<?> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; //这里注意一下,返回的是Gson自定义的,在$Gson$Types里面定义的TypeImpl等,这个类都是继承Type的。 return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); }의 getType 메소드를 살펴보겠습니다.
위 내용은 Java에서 TypeToken을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!