java Type 及其子类介绍

日常 同时被 2 个专栏收录
4 篇文章 0 订阅
4 篇文章 0 订阅

java Type 及其子类介绍

Type 是java反射机制中提供的一个接口,用来表示java中的所有类型的接口,定义如下:

package java.lang.reflect;
public interface Type {
    default String getTypeName() {
        return this.toString();
    }
}

Typejava编程语言中所有类型的通用超级接口,包括原始类型Class,参数化类型,数组类型,类型变量和基本类型。其子类有:

原始类型Class

Class类的实例用来表示java中所有的类, 可以用Class.forName加载一个类,也可以获取到通过一个类的Class对象获取到该类的所有属性,方法,继承的类和接口。

Class<?> clz = MethodHandle.class;
Constructor<?>[] cons = clz.getConstructors();
Method[] methods = clz.getMethods();
Field[] fields = clz.getFields();

泛型数组类型 GenericArrayType

接口GenericArrayType代表泛型数组类型,泛型数组指数组中元素是参数类型或者类型变量。

class GenericArrayTypeTest<T> {
    List<Integer>[] field1;
    T[] field2;
}
public static void genericArrayTest() {
    Class<?> clazz = GenericArrayTypeTest.class;
    try {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Type type = field.getGenericType();
            // 输出 java.util.List<java.lang.Integer>[] / T[]
            System.out.println(type);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

参数化类型ParameterizedType

接口ParameterizedType表示参数化类型,例如Collection<String>;他在反射方法第一次使用参数化类型时被创建,当一个ParameterizedType实例被创建时,将递归解析类型声明中的所有类型参数。

class ParameterizedTypeTest {
    public Map<String, Integer> failed1;
    public List<String> failed2;
}
public class TypeReview {
    public static void main(String[] args) {
        Class<?> clz = ParameterizedTypeTest.class;
        Field[] fields = clz.getFields();
        for (Field field : fields) {
            Type ftype = field.getGenericType();
            if (ftype instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) ftype;
                // 获取参数类型名称,Map<String, Integer>和 List<String>
                System.out.println(parameterizedType.getTypeName());
                // null
                System.out.println(parameterizedType.getOwnerType());
                // 获取原始类型,输出为interface java.util.Map/List
                System.out.println(parameterizedType.getRawType());
                // 获取实际类型参数
                for (Type ptype : parameterizedType.getActualTypeArguments()) {
                    System.out.println(ptype.getTypeName());
                }
            }
        }
    }

}

class ParameterizedTypeTest {

    public Map<String, Integer> failed1;
    public List<String> failed2;

}

类型变量TypeVariable

TypeVariable代表在Java类,构造方法和方法中声明的类型变量:

class TypeVariableTest<T> {
    public <E> TypeVariableTest() {

    }
    public <F> void method1() {

    }
}
public static void main(String[] args) {
    Class<TypeVariableTest> clazz = TypeVariableTest.class;
    TypeVariable<?>[] typeVariable = clazz.getTypeParameters();
    for (TypeVariable<?> variable : typeVariable) {
        System.out.println(variable.getGenericDeclaration());
        System.out.println(variable.getName());
        System.out.println(variable.getTypeName());
    }
    try {
        Method method = clazz.getMethod("method1");
        TypeVariable[] typeVariables = method.getTypeParameters();
        for (TypeVariable variable : typeVariables) {
            System.out.println(variable.getTypeName());
        }
        Constructor<?> constructor = clazz.getConstructor();
        typeVariables = constructor.getTypeParameters();
        for (TypeVariable variable : typeVariables) {
            System.out.println(variable.getTypeName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

WildcardType 通配符类型

表示一个通配符表达式,如?? extends Collection? super List。该接口提供的方法有:

// 返回上界
Type[] getUpperBounds();
// 返回下界
Type[] getLowerBounds();

Mybatis源码中Type使用示例

示例1:org.apache.ibatis.reflection.Reflector中的typeClass方法将Type类型对象转换为Class对象:

private Class<?> typeToClass(Type src) {
    Class<?> result = null;
    // 如果src是Class类型的实例则直接进行强制类型转换
    if (src instanceof Class) {
        result = (Class<?>) src;
    // 如果src是参数类型则获取其原始类型Class对象;
    } else if (src instanceof ParameterizedType) {
        result = (Class<?>) ((ParameterizedType) src).getRawType();
    // 
    } else if (src instanceof GenericArrayType) {
        Type componentType = ((GenericArrayType) src).getGenericComponentType();
        if (componentType instanceof Class) {
        result = Array.newInstance((Class<?>) componentType, 0).getClass();
        } else {
        Class<?> componentClass = typeToClass(componentType);
        result = Array.newInstance(componentClass, 0).getClass();
        }
    }
    if (result == null) {
        result = Object.class;
    }
    return result;
}

Class对象中getField(s)/getDeclaredField(s)区别:

getField(s):

用来获取Class对象所表示类中的公开方法,getMethod(String name , Class<?>... parameterTypes)获取指定名称和参数类型的方法的Method对象,getMethods获取所有公开方法;

getDeclaredField(s)

获取Class对象所表示类中所有声明的方法,参数和返回类型同getMethod(s)

getMethod(s)/getDeclaredMethod(s)getConstructor(s)/getDeclaredConstructor(s)用法与之相似

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

JAVA开发人员必备是HTML格式的 JavaTM 2 Platform Standard Edition 6 API 规范 本文档是 Java 2 Platform Standard Edition 6.0 的 API 规范。 请参见: 描述 Java 2 Platform 软件包 java.applet 提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。 java.awt 包含用于创建用户界面和绘制图形图像的所有类。 java.awt.color 提供用于颜色空间的类。 java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和类。 java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的各类事件的接口和类。 java.awt.font 提供与字体相关的类和接口。 java.awt.geom 提供用于在与二维几何形状相关的对象上定义和执行操作的 Java 2D 类。 java.awt.im 提供输入方法框架所需的类和接口。 java.awt.im.spi 提供启用可以与 Java 运行时环境一起使用的输入方法开发的接口。 java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,即基于 JavaBeansTM 架构的组件。 java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供允许 Java 编程语言代理检测运行在 JVM 上的程序的服务。 java.lang.management 提供管理接口,用于监视和管理 Java 虚拟机以及 Java 虚拟机在其上运行的操作系统。 java.lang.ref 提供了引用对象类,支持在某种程度上与垃圾回收器之间的交互。 java.lang.reflect 提供类和接口,以获得关于类和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。 java.net 为实现网络应用程序提供类。 java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的选择器。 java.nio.channels.spi 用于 java.nio.channels 包的服务提供者类。 java.nio.charset 定义用来在字节和 Unicode 字符之间转换的 charset、解码器和编码器。 java.nio.charset.spi java.nio.charset 包的服务提供者类。 java.rmi 提供 RMI 包。 java.rmi.activation 为 RMI 对象激活提供支持。 java.rmi.dgc 为 RMI 分布式垃圾回收提供了类和接口。 java.rmi.registry 提供 RMI 注册表的一个类和两个接口。 java.rmi.server 提供支持服务器端 RMI 的类和接口。 java.security 为安全框架提供类和接口。 java.security.acl 此包中的类和接口已经被 java.security 包中的类取代。 java.security.cert 提供用于解析和管理证书、证书撤消列表 (CRL) 和证书路径的类和接口。 java.security.interfaces 提供的接口用于生成 RSA Laboratory Technical Note PKCS#1 中定义的 RSA(Rivest、Shamir 和 Adleman AsymmetricCipher 算法)密钥,以及 NIST 的 FIPS-
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值