JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 java 语言的反射机制。
先明确两个概念,静态编译和动态编译。 静态编译:在编译时确定类型,绑定对象,即通过。 动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。 我们可以明确的看出动态编译的好处,而反射就是运用了动态编译创建对象。
Person
package com.cqyti.stx.senior.oop.reflect_; /** * @author JH_Y * @version 1.0 */ class Person { private String id; public String username; public void sayHello(String username) { System.out.println("你好,我是" + username); } private void personInfo(String id) { System.out.println("我的身份证ID是" + id); } }
ReflectDemo
package com.cqyti.stx.senior.oop.reflect_; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author JH_Y * @version 1.0 */ public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<?> clazz = Class.forName("com.cqyti.stx.senior.oop.reflect_.Person"); /* clazz.getField(); //根据方法名,获取反射类申明的public方法 clazz.getDeclaredField(); //根据方法名,获取反射类申明任意方法 */ Field[] declaredFields = clazz.getDeclaredFields();//获取反射类申明的所有属性 for (Field f : declaredFields) { System.out.println(f.getName()); } Field[] fields = clazz.getFields();//获取反射类申明的所有public属性 for (Field f : fields) { System.out.println(f.getName()); } Method[] declaredMethods = clazz.getDeclaredMethods();//获取反射类申明的所有方法 for (Method m : declaredMethods) { System.out.println(m.getName()); } /* sayHello personInfo */ //获取反射类以及父类的所有public方法 Method[] methods = clazz.getMethods(); for (Method m : methods) { System.out.println(m.getName()); } /* 以下除了sayHello都是属于Object类的public方法,(clone 、finalize 、registerNatives不是public修饰,所以没有出现) sayHello wait wait wait equals toString hashCode getClass notify notifyAll */ //根据方法名以及参数类型获取反射类申明的私有方法 Method personInfoMethod = clazz.getDeclaredMethod("personInfo", String.class); personInfoMethod.setAccessible(true); System.out.println(personInfoMethod.getName()); /* personInfo */ /* 调用方法 1. 传统调用: 对象.对象方法---》只能使用该类公有方法,无法使用私有方法 2. 反射调用: 方法对象.invoke(对象,方法所需参数) ---》可以使用该类的公有、私有方法,前提是 personInfoMethod.setAccessible(true); */ Person person = (Person) clazz.newInstance(); person.sayHello("tom"); personInfoMethod.invoke(person, "123456789"); } }