一、Java反射机制简介
1. 指的是可以于运行时加载、探知、使用编译期间完全未知到类;
2. 程序在运行状态中,可以动态加载一个只有名称到类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它都任意一个方法和属性;
3. 加载完类之后,在堆内存中,就产生一个Class类型都对象(一个类只有一个Class对象),这个对象就包含了完整都类都结构信息。可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以形象的称之为:反射。
4. Class类介绍:java.lang.Class类十分特殊,用来表示java中类型【class | interface | enum | annotation | primitive type | void 】本身;Class类的对象包含了某个被加载类的结构;一个被加载的类对应一个Class对象;当一个class被加载,或当加载器(class loader)的defineClasss()被JVM调用,JVM便自动产生一个Class对象;Class类是Reflection的根源;针对任何你想动态加载、运行的类、唯有先获得相应的Class对象。
5. Class类对象获取方式:1)对象.getClass(); 2)Class.forName("路径");3)类名.class。
6. 反射机制常用作用:1)动态加载类、动态获取类的信息(属性、方法、构造器);2)动态构造对象;3)动态调用类和对象的任意方法、构造器;4)动态调用和处理属性;5)获取泛型信息;6)处理注解。
二、
public class Demo01 { public static void main(String[] args) { String path = "com.mimidai.test.User"; try { Class clazz = Class.forName(path); System.out.println("clazz.hashCode()= " + clazz.hashCode()); Class clazz2 = Class.forName(path); System.out.println("clazz2.hashCode()=" + clazz2.hashCode()); /** * 一个类只有一个Class对象 */ System.out.println(clazz.hashCode() == clazz2.hashCode()); /** * Class对象获取方式 */ Class strClazz = String.class; Class strClazz2 = path.getClass(); System.out.println(strClazz == strClazz2); /** * Class对象获取跟数组维度有关 */ Class intClazz = int.class; int[] arr01 = new int[10]; int[][] arr02 = new int[30][3]; int[] arr03 = new int[30]; double[] arr04 = new double[10]; System.out.println("intClazz.hashCode()=" + intClazz.hashCode()); System.out.println("arr01.getClass().hashCode()=" + arr01.getClass().hashCode()); System.out.println("arr02.getClass().hashCode()=" + arr02.getClass().hashCode()); System.out.println("arr03.getClass().hashCode()=" + arr03.getClass().hashCode()); System.out.println("arr04.getClass().hashCode()=" + arr04.getClass().hashCode()); } catch(Exception e) { e.printStackTrace(); } }}
public class Demo02 { public static void main(String[] args) { String path = "com.mimidai.test.User"; try { Class clazz = Class.forName(path); /** * 获取类的名字 */ System.out.println("clazz.getSimpleName(): " + clazz.getSimpleName()); System.out.println("clazz.getName(): " + clazz.getName()); /** * 获取属性信息 */ Field[] fields = clazz.getFields(); System.out.println("fields.length= " + fields.length); for (Field f : fields) { System.out.println("属性:" + f); } Field[] fields2 = clazz.getDeclaredFields(); System.out.println("fields2.length" + fields2.length); for (Field f : fields2) { System.out.println("属性:" + f); } /** * 获取方法信息 */ Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { System.out.println("方法:" + m); } Method m01 = clazz.getDeclaredMethod("getName", null); Method m02 = clazz.getDeclaredMethod("setName", String.class); System.out.println("m01: " + m01); System.out.println("m02: " + m02); /** * 获取构造器信息 */ Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println("构造器:" + constructor); } Constructor constructor = clazz.getDeclaredConstructor(Long.class, String.class, Integer.class); System.out.println("constructor: " + constructor); Classc = (Class )Class.forName(path); /** * 通过反射API调用构造方法、构造对象 * 1. 默认调用了User的无参构造方法 */ User user = c.newInstance(); System.out.println(user); Constructor constructor1 = c.getDeclaredConstructor(Long.class, String.class, Integer.class); User user2 = constructor1.newInstance(100L, "张三", 19); System.out.println("user2.getName(): " + user2.getName()); /** * 通过反射API调用普通方法 */ User user3 = c.newInstance(); Method method = c.getDeclaredMethod("setName", String.class); method.invoke(user3, "哈哈"); System.out.println("user3.getName(): " + user3.getName()); /** * 通过反射API操作属性 */ User user4 = c.newInstance(); Field field = c.getDeclaredField("name"); field.setAccessible(true); field.set(user4, "呵呵"); System.out.println("user4.getName(): " + user4.getName()); System.out.println("field.get(user4): " + field.get(user4)); } catch (Exception e) { e.printStackTrace(); } }}
/** * 通过反射获取泛型信息 */public class Demo03 { public void test01(Mapmap, List list) { System.out.println("Demo03.test01"); } public Map test02() { System.out.println("Demo03.test02"); return null; } public static void main(String[] args) { try { /** * 获取指定方法参数泛型信息 */ Method method = Demo03.class.getMethod("test01", Map.class, List.class); Type[] types = method.getGenericParameterTypes(); for (Type type : types) { System.out.println("##" + type); if (type instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType)type).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("泛型类型:" + genericType); } } } /** * 获取指定方法返回值泛型信息 */ Method method1 = Demo03.class.getMethod("test02", null); Type returnType = method1.getGenericReturnType(); if (returnType instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType)returnType).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("返回值,泛型类型:" + genericType); } } } catch (Exception e) { e.printStackTrace(); } }}