> Java > java지도 시간 > 본문

Java에서 TypeToken을 사용하는 방법

王林
풀어 주다: 2023-05-16 08:49:05
앞으로
1630명이 탐색했습니다.

일반 삭제

우리 모두 알고 있듯이 Java의 제네릭은 런타임 시에만 유효합니다. 즉, List 및 List는 실제로 런타임에 유효합니다. 모두 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> 유형을 직접 전달하지만 런타임 일반 항목이 지워지기 때문에 실제로 얻는 것은 List 유형으로 변환하려면 Gson은 기본적으로 LinkedTreeMap 유형으로 변환합니다.

2. 중괄호 {}가 있는 이유는 무엇인가요? 이 버팀대가 핵심입니다. 우리 모두 알고 있듯이 Java 구문에서 이 컨텍스트에서 {}는 익명 클래스를 정의하는 데 사용됩니다. 이 익명 클래스는 TypeToken의 하위 클래스인 TypeToken 클래스를 상속합니다.

3. 왜 서브클래스를 통해 일반 유형을 얻어야 하나요? 이것이 TypeToken이 일반 유형을 얻을 수 있는 핵심입니다. 이것은 영리한 방법입니다. 아이디어는 다음과 같습니다. List의 제네릭이 지워지고 SubList가 List을 확장하는 하위 클래스를 사용합니다. 이 경우 JVM 내에서 상위 클래스가 일반화됩니까? ?

내 하위 클래스가 상속해야 하는 상위 클래스의 제네릭이 결정되었습니다. 당연히 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!