反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解刨一个类,必须先要获取到该类的字节码文件对象。而解刨使用的就是Class类中的方法。所以先要获取每一个字节码文件对应的Class类型的对象。
阅读API的Class类得知,Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过类加载器中的defineClass方法自动构造的。
package com.zy.demo1; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { public static void main(String[] args) throws Exception { // 做反射第一步,获取某个类的class对象 //第一种方式获取class对象 // User user = new User(); // Class class1 = user.getClass(); //第二种方式获取class对象 Class class2=User.class; //第三种方式 Class class3 = Class.forName("com.zy.demo1.User"); //三选一 //---------------- //就先在的User而言,我们怎么得到一个User对象[只有有构造方法,才能创建对象] //目标:是创建一个User对象 //反射是具有超能力的 //1得到构造对象 Constructor ct = class2.getDeclaredConstructor(); //暴力访问(报错遇到private) //java.lang.IllegalAccessException: Class com.zy.demo1. //Test can not access a member of class com.zy.demo1.User with modifiers "private" ct.setAccessible(true);//强行访问类中指定的私有构造方法 //2利用构造对象,调用api创建一个实例对象 User uu = (User)ct.newInstance(); //3调用User中的一个对象 System.out.println(uu.name);//不加暴力访问公开的name也不能访问 //------------------------------------- //目标2:获取私有属性 //我想拿到User中私有属性 Field df = class2.getDeclaredField("age"); //开暴力访问 df.setAccessible(true); //得到对象 Object object = df.get(uu);//传入刚才得到的一个user对象 //输出 System.out.println(object);//20[已经获取到了private age的值] //目标3:获取私有方法 Method mt = class3.getDeclaredMethod("show"); //开启暴力访问 mt.setAccessible(true); //调用方法 mt.invoke(uu); //小结:一个类中,(属性,方法,构造方法)[公私]都可以任意得到并使用 //-------------------------------------------------- //得到构造对象 Constructor ct2 = class2.getConstructor(int.class,String.class); //创建一个实例 User newInstance = (User)ct2.newInstance(30,"小明"); //输出 System.out.println(newInstance.toString()); Constructor[] constructors = class2.getConstructors(); System.out.println("长度:"+constructors.length);//1 一个公开的 Constructor[] declaredConstructors = class2.getDeclaredConstructors(); System.out.println(declaredConstructors.length);//2 公开私有都包括 //----------------------------------- //属性 Field field = class2.getField("name"); Object object2 = field.get(uu); System.out.println(object2);//花花 //------------------- Field[] fields = class2.getFields(); System.out.println(fields.length);//1 获取公开的 //------------------------ Field[] declaredFields = class2.getDeclaredFields(); System.out.println(declaredFields.length);//2 公开私有都包括 //暴力访问 declaredFields[0].setAccessible(true); declaredFields[1].setAccessible(true); System.out.println(declaredFields[0].get(uu)); System.out.println(declaredFields[1].get(uu)); //--------------------------------------- //方法 Method method = class2.getMethod("speak"); method.invoke(uu); Method[] methods = class2.getMethods(); System.out.println(methods.length);//10 公开的方法[Object9个+自己1个] Method[] declaredMethods = class2.getDeclaredMethods(); System.out.println(declaredMethods.length);//3 自己的公私 } }