zoukankan      html  css  js  c++  java
  • 方法入参获取泛型类型

    1 概述

    • 开发过程中如果需要编写比较通用的代码时,经常需要使用到泛型;
    • 但有时候会被无法获取到泛型类型而困扰,所以写下此篇作为笔记;

    2 常用获取泛型类型方法

    public class GenericTest {
       
        public static void main(String[] args) {
            // 1 false trag为E 错误获取方式。
            List<String> list1 = new ArrayList<>();
            list1.add("test1");
            System.out.println(genericClassName(list1));
    
            // 2 true trag为class java.lang.String 匿名内部类获取方式。
            List<String> list2 = new ArrayList<String>() {
            };
            list2.add("test2");
            System.out.println(genericClassName(list2));
    
            // 3 true trag为class java.lang.String 额外传递匿名内部类获取方式,这种更为常见。
            List<String> list3 = new ArrayList<>();
            list3.add("test3");
            System.out.println(genericClassName(list3, new TypeReference<String>() {
            }));
        }
         
         /**
          * 获取泛型类型
          *
          * @param list
          * @param <T>
          */
         private static <T> boolean genericClassName(List<T> list) {
            Type type = list.getClass().getGenericSuperclass();
            Type trag = ((ParameterizedType) type).getActualTypeArguments()[0];
            T t = list.get(0);
            return t.getClass().equals(trag);
         }
    
         /**
          * 获取泛型类型(更为常见,如:RestTemplate、FastJson、Jackson、Gson都是采用这种方式)
          * 额外入参变量来存储泛型类型来传递
          *
          * @param list
          * @param <T>
          */
         private static <T> boolean genericClassName(List<T> list, TypeReference<T> typeReference) {
            Type type = typeReference.getClass().getGenericSuperclass();
            Type trag = ((ParameterizedType) type).getActualTypeArguments()[0];
            T t = list.get(0);
            return t.getClass().equals(trag);
         }
    
         /**
          * 自定义类型引用类
          */ 
         static class TypeReference<T> {
         }
    }
    

    3 源码:RestTemplate为例

    • 基本使用
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://test.test.com";
        HttpMethod method = HttpMethod.GET;
        HttpEntity httpEntity = null;
        ParameterizedTypeReference<Map<String, Object>> typeReference = new ParameterizedTypeReference<Map<String, Object>>(){};
        Map<String, ?> uriVariables = null;
        // public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables)
        ResponseEntity<Map<String, Object>> responseEntity = restTemplate.exchange(url, method, httpEntity, typeReference, uriVariables);
        Map<String, Object> body = responseEntity.getBody();
    }
    
    • ParameterizedTypeReference类
    public abstract class ParameterizedTypeReference<T> {
        private final Type type;
    
        protected ParameterizedTypeReference() {
            // 与第2章节实现是类似,但对边界条件的检查更为全面,健壮性更好些
            Class<?> parameterizedTypeReferenceSubclass = findParameterizedTypeReferenceSubclass(this.getClass());
            Type type = parameterizedTypeReferenceSubclass.getGenericSuperclass();
            ParameterizedType parameterizedType = (ParameterizedType)type;
            this.type = parameterizedType.getActualTypeArguments()[0];
        }
    
        public Type getType() {
            return this.type;
        }
    
        private static Class<?> findParameterizedTypeReferenceSubclass(Class<?> child) {
            Class<?> parent = child.getSuperclass();
            if (Object.class == parent) {
                throw new IllegalStateException("Expected ParameterizedTypeReference superclass");
            } else {
                return ParameterizedTypeReference.class == parent ? child : findParameterizedTypeReferenceSubclass(parent);
            }
        }
    }
    
  • 相关阅读:
    WSP部署错误—SharePoint管理框架中的对象“SPSolutionLanguagePack Name=0”依赖其他不存在的对象
    Elevate Permissions To Modify User Profile
    Error with Stsadm CommandObject reference not set to an instance of an object
    ASP.NET MVC3添加Controller时没有Scaffolding options
    测试使用Windows Live Writer写日志
    配置TFS 2010出现错误—SQL Server 登录的安全标识符(SID)与某个指定的域或工作组帐户冲突
    使用ADO.NET DbContext Generator出现错误—Unable to locate file
    CSS
    HTML DIV标签
    数据库
  • 原文地址:https://www.cnblogs.com/linzhanfly/p/14979204.html
Copyright © 2011-2022 走看看