3.Members
3.3Constructors
4.数组与枚举类型
4.1数组
4.2枚举
翻译源:Java toturial 反射篇
构造器用来创建类的对象。
获取Constructor
获取特定构造器
Constructor con = c.getConstructor(int.class, int.class); Constructor con = c.getDeclaredConstructor(int.class, int.class);
获取所有构造器
Constructor[] cons = c.getConstructors(); Constructor[] cons = c.getDeclaredConstructors();
获取构造器参数类型
Class[] cpcs = con.getParameterTypes(); Type[] tcs = con.getGenericParameterTypes();note:前者会受到泛型类型擦除的影响,泛型表示为java.lang.Object,后者不会受影响,返回泛型。
判断构造器是否包含变参
boolean b = con.isVarArgs();
判断构造器是否为合成
boolean b = con.isSynthetic();
检索解析修饰符
获取构造器修饰符
int mods = con.getModifiers();ps:无法获取到package-private修饰符,需要手动判断。
Constructor实现了AnnotatedElement接口,提供了检索构造器所持有的注解的API。
创建实例
Constructor.newInstance()与Class.newInstance()都可以用用来创建实例。
Class.newInstance()只能调用无参构造器,Constructor.newInstance()没有参数数量限制。Class.newInstance()会将构造器抛出的异常直接抛出。Constructor.newInstance()抛出包装后的InvocationTargetException。Class.newInstance()要求构造器可见,Constructor.newInstance()可调用private构造器。
Class.newInstance()
Object obj = c.newInstance();
Constructor.newInstance()
Object o = con.newInstance(1);
在JVM的视角,枚举与数组是类。所以Class的方法也可以用于枚举与数组。
反射框架提供了方法用来访问数组类型、数组组件类型、创建新数组检索设置数组组件值。
java.lang.reflect.Array提供了操作数组的方法。
识别数组类型
判断类型是否为数组
boolean b = c.isArray();note:判断Class对象c表示的类型是否为数组,是数组返回true。
获取组件类型
Class c = ac.getComponentType();note:获取Class对象ac表示的数组类型的组件类型。
创建新数组
创建新数组
Object obj = Array.newInstance(c, 5);note:创建长度为5,组件类型为Class对象c表示的类型的数组。
创建数组
String[][][] arr = (String[][][]) Array.newInstance(String.class, 3, 4, 5);note:创建长度为3的三维数组arr。
note:三维数组的组件为长度为4的二维数组,二维数组的组件为长度为5的字符串数组。
访问设置数组及其组件
获取数组组件值
Object ans = Array.get(obj, 2);note:获取数组obj的下标为2的组件的值。
ps:get用于获取引用类型数组的元素。
ps:getInt、getDouble、getFloat、getShort、getLong、getByte、getChar、getBoolean用于获取原始类型数组的元素。
设置数组组件值
Array.set(obj, i, val);note:将数组obj的第i个位置设置为val。
ps:set用于设置元素类型为引用类型的数组的元素。
ps:setInt、setDouble、setFloat、setShort、setLong、setByte、setChar、setBoolean用于设置元素类型为原始类型的数组的元素。
ps:使用setInt方法为Integer类型的数组设值时,由于反射机制发生在运行时,传入的原始类型无法装箱,将导致异常。可以使用set方法传参,解决这一问题。
枚举类型是类,所以使用Class内的方法即可操作枚举类型。
枚举是单例,所以不能实例化,使用反射强行实例化枚举类型会抛出异常。
检验枚举
判断类型是否为枚举
boolean b = c.isEnum();note:如果Class类型对象c表示的类型为枚举,返回true。
获取枚举常量列表
R[] rs = (R[]) c.getEnumConstants();note:如果Class类型对象c表示的类型为枚举,获取此枚举类型定义的所有常量,如果不是枚举返回null。
ps:此方法与枚举对象的默认方法values()效果相同。
ps:此方法按照枚举常量声明的顺序返回枚举常量。
判断域是否为枚举常量
boolean b = f.isEnumConstant();note:判断Field类型对象f表示的域是否为枚举常量,是则返回true。
ps:枚举常量,即定义在枚举类中的常量域。
访问设置枚举类型域
访问设置枚举类型域与访问普通的域没有区别,都是使用Field.get与Field.set方法。