动态代理以及反射小结

1.如何创建Class的实例(重点)

        1.1过程:源文件通过编译(java.exe),生成对应的.class文件。.class文件经过运行(java.exe)这步,就需要进行类的加载(通过JVM的类的加载器),加载到内存中的缓存。每个放入缓存中的.class文件就是一个Class实例!

        1.2 Class的一个对象,对应着一个运行时类。相当于一个运行时类的本身充当了Class的一个实例。

        1.3 java.lang.Class是反射的源头。接下来涉及到反射的类都在java.lang.reflect子包下。如:Field  Method  Constructor  Type  Package...
当通过Class的实例调用getMethods()--->Method,getConstructors()--->Constructor

        1.4 实例化Class的方法(三种):

//1.调用运行时类的本身.class属性
	Class cls1 = Person.class;
	System.out.println(cls1);
	//2.通过运行时类的对象获取
	Person p = new Person();
	Class cls2 = p.getClass();
	System.out.println(cls2);
	//3.(常用)通过Class的静态方法获取,并通过此方法,体会反射的动态性
	Class cls3 = Class.forName("com.reflect.Person");
	System.out.println(cls3);

 

 

 

 

 

 

2.有了Class实例以后,可以做什么?应用一:可以创建对应的运行时类的对象(重点)

	//获取运行时类的对象:方法一
	public void test1() throws Exception{
		Class clazz = Class.forName("com.reflect.Animal");
		Object obj = clazz.newInstance();
		Animal a = (Animal)obj;
		System.out.println(a);
	}

 

 

 

 

 

//调用指定的构造器创建运行时类的对象
	public void test2() throws Exception{
		Class clazz = Animal.class;
		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
		cons.setAccessible(true);
		Animal a = (Animal)cons.newInstance("Tom",10);
		System.out.println(a);
	}

 


3.有了Class实例以后,可以做什么?应用二:获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。
如:Method[] m1 = cls.getMethods():获取到对应的运行时类中声明的权限为public的方法(包含其父类中声明的public)
      Method[] m2 = cls.getDeclaredMethod():获取到对应的运行时类中声明的所有的方法(①任何权限修饰符修饰的都能获取②不含父类中的)

4.有了Class实例以后,可以做什么?应用三:调用对应的运行时类中指定的结构(某个指定的属性、方法、构造器)(重点)

 

	//调用指定属性
	public void test3() throws Exception{
		Class clazz = Class.forName("com.reflect.Animal");
		Object obj = clazz.newInstance();
		Animal a = (Animal)obj;
		//调用非public的属性
		Field f1 = clazz.getDeclaredField("name");
		f1.setAccessible(true);
		f1.set(a, "Jerry");
		//调用public的属性
		Field f2 = clazz.getField("age");
		f2.set(a, 9);
		System.out.println(f2.get(a));
		System.out.println(a);
		//调用static的属性
		Field f3 = clazz.getDeclaredField("desc");
		System.out.println(f3.get(null));
	}

 

	public void test4() throws Exception{
		Class clazz = Class.forName("com.reflect.Animal");
		Object obj = clazz.newInstance();
		Animal a = (Animal)obj;
		
		//调用非public的方法
		Method m1 = clazz.getDeclaredMethod("getAge");
		m1.setAccessible(true);
		int age = (Integer)m1.invoke(a);
		System.out.println(age);
		//调用public的方法
		Method m2 = clazz.getMethod("show", String.class);
		Object returnVal = m2.invoke(a,"金毛");
		System.out.println(returnVal);
		//调用static的方法
		Method m3 = clazz.getDeclaredMethod("info");
		m3.setAccessible(true);
//		m3.invoke(Animal.class);
		m3.invoke(null);
		
	}

 

 

 

5.动态代理————反射的应用。体会反射的动态型
代理设计模式的原理:
       使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用到原始对象上

 

 

静态代理:要求被代理类和代理类同时实现相应的一套接口;通过被代理类的对象调用重写接口的方法时,实际上执行的是被代理类的同样的方法调用。

动态代理:在程序运行时,根据被代理类及其实现的接口,动态的创建一个代理类。当调用代理类的实现的抽象方法时,就发起对被代理类同样方法的调用。
 

 

 

涉及到的技术点:①提供一个实现了InvocationHandler接口实现类,并重写其invoke()方法
                                     ②Proxy.newInstance(obj.getClass().getLoader(), obj.getClass().getInterfaces(), handler);

                                     注:obj:被代理类对象;h:实现了InvocationHanler接口的实现类的对象


附:在程序中用到的Animal类

 

package com.reflect;

public class Animal {
	private String name;
	public int age;
	static String desc = "我是一个动物";
	
	public Animal() {
		super();
		System.out.println("!!!");
	}

	private Animal(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public static void info(){
		System.out.println("动物");
	}
	
	public void show(String desc){
		System.out.println("我是一个:" + desc);
	}
	
	
	
	private int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public static String getDesc() {
		return desc;
	}

	public static void setDesc(String desc) {
		Animal.desc = desc;
	}

	@Override
	public String toString() {
		return "Animal [name=" + name + ", age=" + age + "]";
	}
	
	
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值