反射

1、反射是什么

反射是jvm运行期间,动态的获取class模板的信息(属性、方法等)

2、java提供了Class、AccessibleObject 、Array 、Constructor 、Field 、Method 、Modifier 、Proxy 
类来操作反射信息

2.1 Class 类

Class类提供了反射需要的大部分信息,比如

Class c = Class.forName("main.test.Relf");  //获取模板类
Field  field = c.getField("message");      //读取类属性

2.2 AccessibleObject 类

AccessibleObject提供了设置访问权限(一般要获取私有属性的动态信息,需要设置权限为允许,这是面向对象的封装特性)

RelfEntity relf = new RelfEntity();
Field field = relf.getClass().getDeclaredField("message");
AccessibleObject.setAccessible(new AccessibleObject[]{field},true); //设置访问私有权限
field.set(relf,"hello");
System.out.println(field.get(relf));

2.3 Array类

这个类主要是提供获取反射数组元素信息,比如

RelfEntity relf = new RelfEntity();
Field [] field = relf.getClass().getDeclaredFields();
AccessibleObject.setAccessible(field,true);
Field field1 = (Field) Array.get(field,0);   //获取下标为0的属性
field1.set(relf,"hello");
System.out.println(field1.get(relf));

2.4 Constructor、Field 类

Constructor类基本很少用,里面有可以动态获取参数、参数类型、创建对象等

Field 类用来获取属性信息

2.5 Method 类

Method这个用的比较多,为什么单独说这个方法,是因为我们的动态代理其实也是这个方法中实现的

RelfEntity relf = new RelfEntity();
Method method = relf.getClass().getDeclaredMethod("setMessage",String.class);
method.invoke(relf,"test..."); //动态调用
System.out.println(relf.getMessage());

2.6 Modifier 类

这个类主要是来查看访问类型的,比如我们要查看属性的类型

RelfEntity relf = new RelfEntity();
Field field = relf.getClass().getDeclaredField("message");
int modifier = field.getModifiers();
if(Modifier.isPrivate(modifier)){
    System.out.println("is private");
}

 

2.7 proxy

proxy类是我们实现动态代理的类,首先说下动态代理的思想是解耦,在spring aop就是通过动态代理的方式实现,它可以使得业务逻辑和非业务逻辑分开,比如(我们可以在业务前后加上非业务逻辑处理)

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
    main.test.entity.Proxy proxy = getproxy(new ProxyBook());
    proxy.buySome("java");
}

public static  main.test.entity.Proxy getproxy(main.test.entity.Proxy proxyReal){
    Relf relf = new Relf(proxyReal);
    main.test.entity.Proxy proxy = (main.test.entity.Proxy) Proxy.newProxyInstance(main.test.entity.Proxy.class.getClassLoader(),new Class[]{main.test.entity.Proxy.class},relf);
    return proxy;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("询问是否有货...");  //非业务逻辑之前处理
    method.invoke(entrust,args);
    System.out.println("购买完成...");    //非业务逻辑之后处理
    return null;
}

以上只是简单了介绍了反射的使用,一般需要程序解耦除了需要良好的设计能力还需要语言本身的解耦能力。

 

转载于:https://my.oschina.net/chenping12/blog/1507350

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值