反射一(方法)
1.Class是什么?
Class是一个类,是对象照镜子后可以得到的信息:某个类的数据成员名、方法何构造器、某个类到底实现了那些接口,对于美每个类,JRE都为其保留了一个不变的Class类型的对象,Class对象由系统建立,一个类在JTVM中只会有一个Class实例。
2.Class 获取方法
(1)通过类的class属性获取
Class clazz = String.class; //字符串为类名
(2)通过对象的getClass()方法获取
Class clazz = obj.getClass(); //obj为某个类的实例
(3)通过Class对象的forName()静态方法获取
Class clazz = Class.forName("className");//className为类的全限定名
3.Class类的方法
(1)创建Class对象的方法
Object obj = clazz.newInstance(); //clazz为Class类
注:此方法类必须含有无参构造器
(2)类加载器:用来把类(class)装载到JVM中。
ClassLoader loader = clazz.getClassLoader(); //当前类的类加载器是系统类加载器,还有扩展类加载器和指示类加载器
关于类加载器的一个方法,资源获取:
InputStream in = loader.getResourceAsStream("path");//类加载器直接加载的是当前类目录下边的所有的class文件,包括其他的配置文件,即src下边的所有的文件。
4.反射:是java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API获取到任何类的内部信息,并直接操作对象的内部属性及方法。
(1)获取方法:
//可以本身及其父类的public方法 Method[] methods = clazz.getMethods(); for (Method method :methods){ System.out.println(method); } //仅能获得本身的所有方法,包括私有的 Method[] methods1 = clazz.getDeclaredMethods(); for (Method method :methods1){ System.out.println(method); }
//根据方法名以及参数获取一个方法
Method method = clazz.getMethod("obj",Class<?>); //第一个参数为对象,第二个参数为方法的参数
(2)获取当前类的父类
Class superClazz = clazz.getSuperclass();
(3)执行方法
Object obj = new Student(); Class clazz = obj.getClass(); //根据方法名以及参数获取一个方法 Method method = clazz.getMethod("print",int.class); //执行方法 Object bj = method.invoke(obj,1); System.out.println(bj);
(4)当执行当前类的私有方法时,需要设置方法可访问
Object obj = new Student(); Class clazz = obj.getClass(); Method method =clazz.getDeclaredMethod("print1",int.class);//print1为private方法 method.setAccessible(true);//设置私有方法可以访问 method.invoke(obj,1);
(5)父类的私方法的获取和执行:
//获取当前类或者其父的方法,包括私有方法 public Method getMethod(Class clazz,String methodName,Class ...parameTypes) { //若在当前类找不到方法,将在其父类中找方法 for(;clazz!=Object.class; clazz= clazz.getSuperclass()){ //此处的异常必须用try-catch处理,并且catch不做任何异常抛出 try { Method method = clazz.getDeclaredMethod(methodName,parameTypes); return method; } catch (NoSuchMethodException e) { //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。 //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了 } } return null; } @Test public void testinvoke() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { Object obj = new Student(); Class clazz = Class.forName("reflect.Student"); //当前类的私有方法 Method method1 = getMethod(clazz,"print1",int.class); System.out.println(method1); method1.setAccessible(true); method1.invoke(obj,1); //父类的私有方法 Method method2 = getMethod(clazz,"setIdAndName",int.class,int.class); method2.setAccessible(true); System.out.println(method2); method2.invoke(obj,2,1); }