1. 反射机制是什么?
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能被成为java反射机制。
2.反射机制能做什么?
反射机制提供了以下功能:
- 在运行时判断一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断一个类所具有的成员变量和方法
- 在运行时调用一个对象的方法
- 生成动态代理
3.反射机制的优缺点
静态编译:在编译时确定类型,绑定对象,即可通过
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,以降低类之间的耦合性。
反射机制的优点就是:可以实现动态创建对象和编译,体现出很大的灵活性。比如,一个大型的软件,不可能一次性把它设计的很完美。一个程序编译通过发布了,当发现需要更新某些功能时,我们不可能把以前的卸载,否则软件就没人用了。采用静态编译的话,需要把整个程序重新编译才可以实现功能的更新,而采用反射机制的话,就可以不用卸载,只需要运行时动态的创建和编译,就可以实现功能。缺点是对性能有影响,反射是一种解释操作,我们告诉jvm, 我们希望做什么,这总是慢于执行相同的操作。
4.反射机制的相关API
- 通过一个对象获得完整的包名和类名
public class TestReflect {public static void main(String[] args) {TestReflect testReflect = new TestReflect();System.out.println(testReflect.getClass().getName());} }
- 实例化Class类对象
public class TestReflect1 {public static void main(String[] args) throws ClassNotFoundException {Class<?> class1 = null;Class<?> class2 = null;Class<?> class3 = null;class1 = Class.forName("com.atguigu.java1.TestReflect1");class2 = new TestReflect1().getClass();class3 = TestReflect1.class;System.out.println(class1.getName());System.out.println(class2.getName());System.out.println(class3.getName());} }
- 获取一个对象的父类与实现的接口
public class TestReflect3 implements Serializable{private static final long serialVersionUID = 1L;public static void main(String[] args) throws ClassNotFoundException {Class<?> clazz = Class.forName("com.atguigu.java1.TestReflect3");//获取父类Class<?> parentClazz = clazz.getSuperclass();System.out.println(parentClazz.getName());//获取所有接口Class<?> intes[] = clazz.getInterfaces();for(int i = 0; i < intes.length ;i++){System.out.println(intes[i].getName());}} }
- 获取类的全部构造函数,通过反射机制实例化一个类的对象
public class TestReflect4 {public static void main(String[] args) throws Exception {//实例化Class对象Class<?> clazz = User.class;//通过反射机制实例化一个类的对象 默认构造方法,调用set赋值User user = null;user = (User) clazz.newInstance();user.setAge(20);user.setName("Rick");System.out.println(user);//获取全部的构造函数 使用构造函数赋值Constructor<?> cons[] = clazz.getConstructors();//查看每个构造方法需要的参数for(int i = 0; i < cons.length; i++){Class<?> clazzs[] = cons[i].getParameterTypes();System.out.print("cons[" + i + "]" );for(int j = 0; j<clazzs.length;j++){System.out.print(clazzs[j].getName() +" ");}System.out.println();}user = (User) cons[0].newInstance("RICK");System.out.println(user);user = (User) cons[1].newInstance("RICK",20);System.out.println(user);} }class User{private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public User(){}public User(String name){this.name = name;}public User(String name, int age){this.name = name;this.age = age;}@Overridepublic String toString() {return "User [name=" + name + ", age=" + age + "]";}}
- 获取某个类的全部属性
public class TestReflect6 implements Serializable{/*** */private static final long serialVersionUID = 1L;public static void main(String[] args) throws ClassNotFoundException {Class clazz = Class.forName("com.atguigu.java1.TestReflect6");Method method[] = clazz.getMethods();for(int i = 0; i < method.length; i++){Class<?> returnType = method[i].getReturnType();Class<?> para[] = method[i].getParameterTypes();int temp = method[i].getModifiers();System.out.print(Modifier.toString(temp) + " ");System.out.print(returnType.getName() + " ");System.out.println(method[i].getName() + "");for(int j = 0; j < para.length -1; j++){System.out.println(para[i].getName()); }Class<?> exce[] = method[i].getExceptionTypes();if(exce.length > 0){System.out.println("异常");for(int k = 0; k <exce.length -1; k++){System.out.print(exce[k].getName() +" ");}}System.out.println(); }} }
- 通过反射机制调用某个类的方法
public class TestReflect7 {public static void main(String[] args) throws Exception {Class<?> clazz = Class.forName("com.atguigu.java1.TestReflect7");Method method = clazz.getMethod("reflect1");method.invoke(clazz.newInstance());Method method2 = clazz.getMethod("reflect2", int.class,String.class);method2.invoke(clazz.newInstance(), 20,"Rick");}public void reflect1(){System.out.println("Java 反射机制 调用方法1");}public void reflect2(int age, String name){System.out.println("Java 反射机制 调用方法2");System.out.println(age + " " + name);} }
-
通过反射机制操作某个类的属性
public class TestReflect8 {private String property = null;public static void main(String[] args) throws Exception {Class<?> clazz = TestReflect8.class;Object obj = clazz.newInstance();Field field = clazz.getDeclaredField("property"); field.setAccessible(true);field.set(obj, "java反射机制");System.out.println(field.get(obj));} }
- 反射机制的动态代理
//定义项目接口 interface Subject{public String say(String name, int age); }//定义真实项目 class RealSubject implements Subject{@Overridepublic String say(String name, int age) {return name + " " + age;} }class MyInvocationHandler implements InvocationHandler{private Object obj; //真实类的对象public Object bind(Object obj){this.obj = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object temp = method.invoke(this.obj, args);return temp;} }public class TestReflect9 {public static void main(String[] args) {MyInvocationHandler demo = new MyInvocationHandler();Subject sub = (Subject) demo.bind(new RealSubject());String info = sub.say("Rich", 20);System.out.println(info);} }