1.简介
反射API可以获取程序在运行时刻的内部结构,反射API提供的动态代理是非常强大的功能,可以原生的实现AOP中的方法拦截功能,反射API就好像在看一个Java类在水中的倒影,知道Java类的内部结构,就可以和它们进行交互,包括创建对象,调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现中,java反射的性能有很大的提升,在灵活和性能中需权衡2.基本用法
反射API的第一个主要作用就是在程序运行时获取内部结构,能遍历出一个Java类中所有的内部结构,反射API的另一个强大的功能就是能在运行时刻操作java对象进行操作,包括动态的创建一个java类对象,获取每个域的值,以及调用某个方法package com.reflect;import java.util.List;/** * Person类 为后续的反射的使用服务 为方便程序调试,本程序中全部使用JUnit测试 */public class Person { // 设置字段 public String name = "name"; private int age; private static double height; // 无参构造方法 public Person() { System.out.println("Person"); } // 含参构造方法 public Person(String name) { System.out.println("Person" + name); } public Person(String name, int password) { System.out.println("Person" + name + password); } private Person(List list) { System.out.println("list"); } // 其他共有方法 public void aa(String name, int password) { System.out.println(name + ":" + password); } public void bb(String name, int[] password) { System.out.println(name + ":password数组"); } public Class[] cc() { return new Class[] { String.class }; } public static void dd() { System.out.println("静态方法"); } // 私有方法 private void ee() { System.out.println("私有方法ee"); } // main方法 public static void main(String[] args) { System.out.println("main 方法"); }}package com.reflect;/** * 反射:加载类的方法 */public class demo1 { public static void main(String[] args) throws Exception { //加载类的方法一 Class clazz1=Class.forName("com.reflect"); //加载类的方二 Class clazz2=new Person().getClass(); //加载类的方法三 Class clazz3=Person.class; }}package com.reflect;import java.lang.reflect.Constructor;import java.util.Arrays;import java.util.List;import org.junit.Test;/** * 反射类的构造方法 * @author Administrator */public class demo2 { //反射构造函数Person() @Test public void test1() throws Exception { Class clazz = Class.forName("com.reflect.Person"); Constructor c = clazz.getConstructor(null); Person p = (Person)c.newInstance(null); System.out.println(p.name);//测试对象是否创建成功 } //反射构造函数Person(String name) @Test public void test2() throws Exception{ Class clazz=Class.forName("com.reflect.Person"); Constructor c=clazz.getConstructor(String.class); Person p=(Person) c.newInstance("python"); System.out.println(p.name);//测试对象是否创建成功 } //反射构造函数Person(String name,int password) @Test public void test3() throws Exception{ Class clazz=Class.forName("com.reflect.Person"); Constructor c=clazz.getConstructor(String.class,int.class); Person p=(Person) c.newInstance("wangxiao",123456); System.out.println(p.name); } //反射私有构造函数Person(List list) @Test public void test4() throws Exception { Class clazz = Class.forName("com.reflect.Person"); Constructor c = clazz.getDeclaredConstructor(List.class); c.setAccessible(true); int[] a = {2,3,4}; List list = Arrays.asList(a); Person p = (Person)c.newInstance(list); System.out.println(p.name);//测试对象是否创建成功 } //反射对象的另一种方法,默认无参构造函数 @Test public void test5() throws Exception{ Class clazzClass=Class.forName("com.reflect.Person"); Person p=(Person) clazzClass.newInstance(); System.out.println(p.name);//测试对象是否创建成功 }}package com.reflect;import java.lang.reflect.Method;import org.junit.Test;/** * 解剖类的所有方法 */public class demo3 { //反摄aa() @Test public void test1() throws Exception{ System.out.println("test1程序结果--------------"); Class clazzClass=Class.forName("com.reflect.Person"); Person p=(Person) clazzClass.newInstance(); Method method=clazzClass.getMethod("aa", String.class,int.class); method.invoke(p, "wangxiao",123); } //反射bb() @Test public void test2() throws Exception { System.out.println("test2程序结果------------"); Class clazz = Class.forName("com.reflect.Person"); Person p=(Person) clazz.newInstance(); Method m=clazz.getMethod("bb",String.class, int[].class); int[] a ={1,2,3}; m.invoke(p,"zzw", a); } //反射cc() @Test public void test3() throws Exception { System.out.println("test3程序结果------------"); Class clazz = Class.forName("com.reflect.Person"); Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("cc",null); Class[] c= (Class[]) m.invoke(p,null); for(Class cla:c) System.out.println(cla.getName()); } //反射dd() @Test public void test4() throws Exception { System.out.println("test4程序结果------------"); Class clazz = Class.forName("com.reflect.Person"); Method m = clazz.getMethod("dd",null); m.invoke(null,null);//静态方法可以不用对象,当然加对象也不会出错 } //反射ee() @Test public void test5() throws Exception { System.out.println("test5程序结果------------"); Class clazz = Class.forName("com.reflect.Person"); Person p = (Person) clazz.newInstance(); Method m = clazz.getDeclaredMethod("ee",null); m.setAccessible(true);//设置查看私有方法的权限 m.invoke(p,null); } //反射 main(),注意此处的参数传递方法 @Test public void test6() throws Exception { System.out.println("test6程序结果------------"); Class clazz = Class.forName("com.reflect.Person"); Method m = clazz.getDeclaredMethod("main",String[].class); m.invoke(null,new Object[]{new String[]{"aa","bb"}});//正确 m.invoke(null,(Object)new String[]{"aa","bb"});//正确 }}