Java 反射

	Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
	对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。

优点:

  1. 增加程序灵活性。
  2. 提高代码复用性。

缺点:

  1. 反射操作的效率要比那些非反射操作低得多
    ps:这肯定比你直接调用来慢得多。
    反射大概比直接调用慢50~100倍,但是需要你在执行100万遍的时候才会有所感觉.

    如果你只是偶尔调用一下反射,请忘记反射带来的性能影响
    如果你需要大量调用反射,请考虑缓存。
  2. 模糊内部逻辑
    ps:你发现没有是操作的 .class字节码
    反射等绕过了源代码的技术,因而会带来维护问题
  3. 安全限制
    反射技术要求程序必须在一个没有安全限制的环境中运行
  4. 内部暴露
    ps:你发现没有,private 都不管用了。
    由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法)

使用方法:
1.获取对象.class文件

Person p1 = new Person();
Class c1 = p1.getClass();


Class c2 = Person.class;


Class c3 = Class.forName(“com.ys.reflex.Person”);

2.通过方法,来执行你所要达到的要求.

常用方法:


 //获得类完整的名字
 String className = c2.getName();
 System.out.println(className);//输出com.ys.reflex.Person
    
//获得类的public类型的属性。
 Field[] fields = c2.getFields();
 for(Field field : fields){
     System.out.println(field.getName());//age
 }
//获得类的所有属性。包括私有的
Field [] allFields = c2.getDeclaredFields();
for(Field field : allFields){
    System.out.println(field.getName());//name    age
}
//获得类的public类型的方法。这里包括 Object 类的一些方法
Method [] methods = c2.getMethods();
for(Method method : methods){
    System.out.println(method.getName());//work waid equls toString hashCode等
}
 //获得类的所有方法。 .invoke()的使用.
 Method [] allMethods = c2.getDeclaredMethods();
for(Method method : allMethods){
    System.out.println(method.getName());//work say
}
 // 方法的反射操作
 // a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
 // 方法如果没有返回值返回null,有返回值返回具体的返回值
 // Object o = m.invoke(a1,new Object[]{10,20});
 
  Method m = c.getMethod("print", int.class, int.class); //print方法,参数是两个 int
  
  Object o = m.invoke(a1, 10, 20);//调用方法,左边为方法返回值
// 获取方法print(String,String)
   Method m1 = c.getMethod("print", String.class, String.class);
   o = m1.invoke(a1, "hello", "WORLD");//调用
 //获得指定的属性
 Field f1 = c2.getField("age");
 System.out.println(f1);
 //获得指定的私有属性
 Field f2 = c2.getDeclaredField("name");
 //启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
 f2.setAccessible(true);
 //创建这个类的一个对象
 Object p2 =  c2.newInstance();
 //将 p2 对象的  f2 属性赋值为 Bob,f2 属性即为 私有属性 name
 f2.set(p2,"Bob");
 //使用反射机制可以打破封装性,导致了java对象的属性不安全。 
 System.out.println(f2.get(p2)); //Bob

动态代理:

/**
 * 顶层接口
 * @author yujie.wang
 *
 */
public interface Person {
	public void sayHello(String content, int age);
	public void sayGoodBye(boolean seeAgin, double time);
}

/**
 * 需要被代理的类 实现了一个接口Person
 * @author yujie.wang
 *
 */
public class Student implements Person{
 
	@Override
	public void sayHello(String content, int age) {
		// TODO Auto-generated method stub
		System.out.println("student say hello" + content + " "+ age);
	}
 
	@Override
	public void sayGoodBye(boolean seeAgin, double time) {
		// TODO Auto-generated method stub
		System.out.println("student sayGoodBye " + time + " "+ seeAgin);
	}
 
}

/**
 * 动态代理,动态代理类不要显示的实现被代理类所实现的接口 ,实现InvocationHandler接口
 * @author yujie.wang
 *
 */
public class MyInvocationHandler implements InvocationHandler{
	
	private Object object;
	
	public MyInvocationHandler(Object object){
		this.object = object;
	}
 
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("MyInvocationHandler invoke begin");
		System.out.println("proxy: "+ proxy.getClass().getName());
		System.out.println("method: "+ method.getName());
		for(Object o : args){
			System.out.println("arg: "+ o);
		}
		//通过反射调用 被代理类的方法
		method.invoke(object, args);
		System.out.println("MyInvocationHandler invoke end");
		return ;
	}
	
	public static void main(String [] args){
		//创建需要被代理的类
		Student s = new Student();
		//这一句是生成代理类的class文件,前提是你需要在工程根目录下创建com/sun/proxy目录,不然会报找不到路径的io异常
		System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
		//获得加载被代理类的 类加载器
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		//指明被代理类实现的接口
		Class<?>[] interfaces = s.getClass().getInterfaces();
		// 创建被代理类的委托类,之后想要调用被代理类的方法时,都会委托给这个类的invoke(Object proxy, Method method, Object[] args)方法
		MyInvocationHandler h = new MyInvocationHandler(s);
		//生成代理类
		Person proxy = (Person)Proxy.newProxyInstance(loader, interfaces, h);
		//通过代理类调用 被代理类的方法
		proxy.sayHello("yujie.wang", 20);
		proxy.sayGoodBye(true, 100);
		System.out.println("end");
	}
 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值