java 反射
1、反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。
Java反射机制主要提供了以下功能:
- 在运行时构造任意一个类的对象
- 在运行时获取任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法(属性)
- 生成动态代理
2、相关API使用
Constructor:
/** * 构造器 * @param user */ public static void constructor(User user) { Class<? extends User> aClass = user.getClass(); Constructor[] cs = aClass.getDeclaredConstructors(); for (Constructor constructor : cs) { System.out.print(constructor.getName() + "("); //获取构造函数的参数列表---》得到的是参数雷彪的类类型 Class[] paramTypes = constructor.getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName() + ","); } System.out.println(")"); } }
Field:
/** * 字段 * * @param user * @throws Exception */ public static void field(User user) throws Exception { Class<? extends User> aClass = user.getClass(); System.out.println("getFields public修饰的>>>>>>>"); Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); } System.out.println("getDeclaredFields获取一个类的所有字段>>>>>>>"); Field[] declaredFields = aClass.getDeclaredFields(); for (Field field : declaredFields) { System.out.println("field.getName()>>>" + field.getName() + " " + field.getType().getSimpleName()); //name属性 if ("name".equals(field.getName())) { // 要设置属性可达,不然会抛出IllegalAccessException异常 field.setAccessible(Boolean.TRUE); System.out.println(" 1>>>" + field.get(user)); //重新设置值 field.set(user, "jack"); System.out.println(" 2>>>" + field.get(user)); field.setAccessible(Boolean.FALSE); } } System.out.println("单个字段"); try { Field name = aClass.getField("city"); System.out.println(name.getName()); } catch (NoSuchFieldException e) { e.printStackTrace(); } }
Method:
/** * 方法 * * @param user * @throws Exception */ public static void method(User user) throws Exception { Class<? extends User> aClass = user.getClass(); System.out.println("getMethods public修饰的>>>>>>>"); Method[] methods = aClass.getMethods(); for (Method method : methods) { // System.out.println(method.getName()); } System.out.println("getDeclaredMethods当前类自己的所有方法>>>>>>>"); Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method method : declaredMethods) { System.out.print(method.getName() + "("); //获取参数类型 Class<?>[] parameterTypes = method.getParameterTypes(); for (Class parameterType : parameterTypes) { System.out.print(parameterType.getName() + ","); } System.out.println(")"); if ("print".equals(method.getName())) { method.invoke(user); } if ("hello".equals(method.getName())) { // 要设置属性可达,不然会抛出IllegalAccessException异常 method.setAccessible(Boolean.TRUE); method.invoke(user); method.setAccessible(Boolean.FALSE); } if ("say".equals(method.getName())) { // 要设置属性可达,不然会抛出IllegalAccessException异常 method.setAccessible(Boolean.TRUE); //参数对上 method.invoke(user, "yyy"); method.setAccessible(Boolean.FALSE); } } Method method = aClass.getMethod("print"); System.out.println("method.getName()=====" + method.getName()); }
3、Class获取方式
//实际告诉我们任何一个类都有一个隐含的静态成员变量class(知道类名时用),不会触发初始化 Class c1 = User.class; //已知该类的对象通过getClass方法(知道对象时用) Class c2 = user.getClass(); //会有一个ClassNotFoundException异常,会触发初始化 Class c3 = Class.forName("类的路径全名");
可用Class进行对象实例创建:
//前提是必须要有无参的构造方法,因为该语句会去调用其无参构造方法。该语句会抛出异常。 User user = (User)c1.newInstance();
源码参照:Github