一:反射的理解
Reflection(反射)是指被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API 取得任何类的内部信息,并直接操作任意对象的内部属性及方法。
框架=反射+注解+设计模式
二:体会反射机制的“动态性”
// 创建一个指定类的对象,classpath:指定类的全类名
public Object getInstance(String classpath) throws Exception {Class clazz = Class.forName(classpath);return clazz.newInstance();
}@Test
public void test2() {Random random = new Random();String classpath="";for (int i = 0; i < 100; i++) {int number = random.nextInt(3);switch (number) {case 0:classpath = "java.util.Date";break;case 1:classpath = "java.lang.Object";break;case 2:classpath = "com.cn.test.Person";break;}try {Object obj=getInstance(classpath);System.out.println(obj);} catch (Exception e) {e.printStackTrace();}}
}
三:反射机制能提供的功能
》在运行时判断任意一个对象所属的类
》在运行时构造任意一个类的对象
》在运行时判断任意一个类所具有的成员变量和方法
》在运行时获取泛型信息
》在运行时调用任意一个对象的成员变量和方法
》在运行时处理注解
》生成动态代理
四:相关API
java.lang.Class :反射的源头
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor
五:关于Class类的理解
1.类的加载过程:
程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。
接着我们使用java.exe 命令 对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,在此过程就称为类的加载。加载到内存中的类,我们称为运行时类,此运行时类,就作为Class 的一个实例。
2.换句话说,Class的实例 对应着 一个运行时类。
3.加载到内存中的运行时类会缓存一定的时间,在此时间之内,我们可以通过不同方式来获取此运行时类。
4.获取Class实例的几种方式:
@Test
public void test3() throws ClassNotFoundException {//1.调用类.class 属性,获取Class实例Class class1= Person.class;System.out.println(class1);Person p =new Person();//2.调用getClass(),获取Class实例Class class2= p.getClass();System.out.println(class2);//3.Class.forName,获取Class实例 Class class3 = Class.forName("com.cn.test.Person");System.out.println(class3);//4.调用类的加载器getClassLoader(),获取Class实例ClassLoader classLoader = Reflection1Test.class.getClassLoader();Class class4= classLoader.loadClass("com.cn.test.Person");System.out.println(class4);//System.out.println(class1==class2);
5. 总结:创建类的对象的方式
方式一: new + 构造器
方式二:要创建Xxx类的对象,可以考虑:Xxx/Xxxs 类是否有静态方法存在,可以调用其静态方法,创建Xxx对象。
方式三:通过反射
6.Class实例可以是哪些结构的说明
1)class:外部类,成员(成员内部类,静态内部类)局部内部类,匿名内部类
2)interface:接口
3) []:数组
4)enum:枚举
5)annotation:注解@interface
6)primitive type:基本数据类型
7)void
7.类的加载器,加载配置文件
@Test public void test3() throws IOException {//方式一Properties pro =new Properties();FileInputStream fis =new FileInputStream("jdbc.propertities");pro.load(fis);String name = pro.getProperty("name");String age = pro.getProperty("age");System.out.println(name+":"+age);} @Test public void test4() throws IOException {//方式二,该方式文件放在src目录下ClassLoader classLoader = Reflection2Test.class.getClassLoader();InputStream resourceAsStream = classLoader.getResourceAsStream("jdbc2.propertities");Properties pro =new Properties();pro.load(resourceAsStream);String name = pro.getProperty("name");String age = pro.getProperty("age");System.out.println(name+":"+age);}
六:反射的实例
1.获取所有的属性,方法,构造器
@Test public void test2() {Class clazz = Person.class;//获取运行时类及其所有父类的public方法Method[] methods = clazz.getMethods();for (Method m : methods) {System.out.print(m + "\t");System.out.println(m.getName());}System.out.println();//获取运行时类所有方法Method[] declaredMethods = clazz.getDeclaredMethods();for (Method m : declaredMethods) {System.out.print(m + "\t");System.out.println(m.getName());}}@Test public void test3() {Class clazz = Person.class;//获取运行时类所有public的构造器Constructor[] constructors = clazz.getConstructors();for(Constructor c:constructors){System.out.println(c);}System.out.println();//获取运行时类所有构造器Constructor[] constructors2 = clazz.getDeclaredConstructors();for(Constructor c:constructors2){System.out.println(c);}} @Test public void test4() throws Exception {//获取当前运行时类父类的对象Class superclass = Person.class.getSuperclass();System.out.println(superclass);
}
2.获取指定的属性,方法,构造器
@Test
public void filedTest() throws Exception {Class clazz=Person.class;Object obj = clazz.newInstance();Person per= (Person) obj;//获取指定属性Field name = clazz.getDeclaredField("name");//给指定对象属性复制name.set(per,"tom");System.out.println(name.get(per));//给静态属性赋值,并获取Field hobbies = clazz.getDeclaredField("hobbies");hobbies.set(clazz,"baskball");System.out.println(hobbies.get(clazz));
}@Test
public void methodTest() throws Exception {Class clazz=Person.class;Object obj = clazz.newInstance();Person per= (Person) obj;//获取public 无参方法 并调用Method info = clazz.getDeclaredMethod("info");info.invoke(per);//获取public 有参方法 并调用Method getNation = clazz.getDeclaredMethod("getNation",String.class);getNation.invoke(per,"china");//获取静态方法并调用Method study = clazz.getDeclaredMethod("study");study.invoke(clazz);//获取私有方法并调用Method getAge = clazz.getDeclaredMethod("getAge", int.class);//设置为可访问getAge.setAccessible(true);System.out.println(getAge.invoke(per, 20));}@Test
public void ConstructTest() throws Exception {Class clazz= Person.class;//该方法为常用用法,具有通用性Object o = clazz.newInstance();System.out.println(o);//获取带有参数的构造器,不常用Constructor constructor = clazz.getDeclaredConstructor(int.class, String.class);constructor.setAccessible(true);Object jerry = constructor.newInstance(15, "jerry");System.out.println(jerry);}
七:反射的应用:动态代理
1.静态代理:
interface ColthFactory{void produceColth(); } //代理类 class ProxyColthFactory implements ColthFactory{private ColthFactory factory;public ProxyColthFactory(ColthFactory factory){this.factory=factory;}@Overridepublic void produceColth() {System.out.println("生产衣服之前的准备工作");factory.produceColth();System.out.println("生产衣服之后的收尾工作");} } //被代理类 class NIkeColthFactory implements ColthFactory{@Overridepublic void produceColth() {System.out.println("NIKE生产衣服");} }public class StaticProxyTest {public static void main(String[] args) {//创建被代理类对象NIkeColthFactory nike =new NIkeColthFactory();//创建代理类对象ProxyColthFactory proxy =new ProxyColthFactory(nike);//调用方法proxy.produceColth();} }
2.动态代理:
class ProxyFactory{public static Object getInstance(Object obj){MyInvocationHandler hander= new MyInvocationHandler();hander.blind(obj);return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hander);} }class MyInvocationHandler implements InvocationHandler{private Object obj; //赋值时必须传被代理类实例public void blind(Object obj){this.obj=obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object invoke = method.invoke(obj, args);// method为代理类调用的方法,此方法也作为被代理类对象要调用的方法return invoke;} }public class ProxyTest {public static void main(String[] args) {NIkeColthFactory nike = new NIkeColthFactory();ColthFactory colthFactory= (ColthFactory) ProxyFactory.getInstance(nike);colthFactory.produceColth();} }