反射

反射

反射机制是java动态性的特性之一;

反射的由来:
动态语言:在程序运行时,可以改变程序结构或者变量类型,典型的语言:Pathon,javescript等;
C,C++,JAVA并不是动态语言,但是JAVA有一定的动态性,它是准动态语言,我们可以利用反射机制、字节码操作获得类似动态语言的特性;

反射机制;
指的是可以在运行时加载、探知、使用编译期间完全未知的类;
程序在运行过程中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构;
这个对象就像一面镜子,透过这面镜子看到类的结构,所以,我们称之为反射;

对象是表示或者封装一组信息;当类被加载后,JVM会创建一个对应类的Class对象,类的整个结构信息会存放到对应的Class对象中;

反射的常见作用
①动态加载类,动态获取类的信息(属性,方法,构造器);
②动态构造对象
③动态调用类和对象的任意方法,构造器
④动态调用和处理属性
⑤获取泛型信息
⑥处理注解

1.获取Class对象几种方式
String path = "com.example.mydemo7.MyClass";
MyClass myClass = new MyClass() ;
Class<?> class1 = Class.forName(path);
Class class2 = MyClass.class ;
Class class3 = myClass.getClass();
class1,class2,class3是同一个对象

int[] arr1 = new int[10];
int[] arr2 = new int[30];
arr1和arr2的Class对象也是同一个;

int[] arr1 = new int[10];
int[][] arr3 = new int[10][10];
arr1和arr3的Class对象并不是同一个;

2.通过反射获取属性
//只能获取所有public修饰的属性
Field[] field1 = class1.getFields();
//获取所有属性,包含private
Field[] field2 = class1.getDeclaredFields();
//通过指定名称获取相应的属性
Field filed3 = class1.getDeclaredField("name");

3.通过反射获取方法
//只能获取所有public修饰的方法
Method[] method1 = class1.getDeclaredMethods() ;
//获取所有方法,包含private
Method[] method2 = class1.getMethods() ;
//通过指定名称获取相应的方法
Method method3 = class1.getDeclaredMethod("setName", String.class) ;

4.获取构造函数
//获取所有构造器,包含private
Constructor[] constructor1 = class1.getDeclaredConstructors();

5.构造对象
//构造对象,使用无参构造器,所以javebean必须要有无参的构造器
MyClass clazz = (MyClass) class1.newInstance();
                    
//构造对象,使用有参构造器
Constructor constructor2 = class1.getDeclaredConstructor(null);
MyClass clazz1 = (MyClass) constructor2.newInstance(null);

6.调用方法以及属性
//调用方法
method3.invoke(clazz1, "renshuguo");
                    
//操作属性
filed3.setAccessible(true);//该属性不用检查,直接访问,故可以操作私有属性
filed3.set(clazz1, "renshuguo");
//获取属性
String name = (String) filed3.get(clazz1);

7.反射机制的性能问题
反射机制会造成程序的性能比较慢,比较差;
反射的运行速度比正常的要慢30倍左右;不做安全检查的反射比正常的反射快7倍左右;
优化方案:
①setAccessible(true),禁止安全检查,提高反射的运行速度;

8.反射操作泛型
JAVA通过泛型擦除的机制来引入泛型,java中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换的麻烦;一旦编译完成,所有的和泛型有关的类型全部擦除;

9.反射操作注解


积累;
1,获取一个方法时可以通过反射,反射的时候要得到class对象,如果该方法在class的父类中,本class中没有,反射时会报找不到该方法的异常,此时需要获取父类的class的对象,然后再去反射;
如:
Window window = getWindow() ;
Class<? extends Window> clazz = (Class<? extends Window>) window.getClass().getSuperclass();
Method method = clazz.getDeclaredMethod("shouldCloseOnTouch", Context.class,MotionEvent.class);
method.setAccessible(true);
shouldCloseOnTouch = (boolean) method.invoke(window, getContext(),event);

转载于:https://my.oschina.net/u/3491256/blog/1543932

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值