Android面试系列文章2018之Java部分反射机制篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClAndEllen/article/details/79393029

Android面试系列文章2018之Java部分反射机制篇

1.编译时与运行时

1.1 编译时

  编译时:将Java代码编译成.class文件的过程。

1.2 运行时

  运行时类型:就是Java虚拟机执行.class文件的过程。

1.3 编译时类型和运行时类型

  编译时类型:编译时类型由声明该变量时使用的类型决定。

  运行时类型:运行时类型由实际赋给该变量的对象决定。

Animal animal = new Dog();
-------------   ----------
 编译时类型      运行时类型

1.4 动态绑定

1.在编译时,是调用声明类型的成员方法(多态实现原理),也就是所谓的编译时类型的方法。

2.导论运行时,调用的是实际的类型的成员方法,也就是所谓的运行时类型的方法。

3.对于调用引用实例的成员变量,无论是编译时还是运行时,均可是调用编译时类型的成员变量。

2.什么是反射?

  在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意的方法和属性。

3.class类

.class文件:是由一个.java文件通过编译过程生成的.class文件。

Class对象:当Java虚拟机加载一个.class文件到内存时,都会生成一个对应的Class对象,注意的是这个Class对象有且只有一个存在于内存当中。

4.Class对象获取的3种方式

[1]通过对象来获取Class文件对象

Person p = new Person();
Class  c = p.getClass();

[2]通过类的getClass()方法获取Class文件对象

Class c = Person.getClass();

[3]通过Class的forName()方法来获取(开发选的方式)

Class c = Class.forName("com.ellen.Person");//注意传入的一定是全路径,不然会报错比如下面
Class c = Class.forName("Person");//报错

5.反射的用法

5.1 通过反射获取构造函数

[1]获取多个看得见的构造函数(看得见是指可以在此处访问的构造函数)

Class c = Class.forName(Path);
Constructor[] cons = c.getConstructors();

[2]获取所有的构造函数

Class c = Class.forName(Path);
Constructor[]  cons1 = c.getDeclaredConstructors();

[3]获取单个构造函数

Class c = Class.forName(Path);

//返回能看见的无参构造函数对象 
Constructor con1 =  c.getConstructor();
Object obj = con1.newInstance();
Person p = (Person)obj;

//返回能看见的带参构造函数对象 
Constructor con2 =  c.getConstructor(String.class,int.class,String.class);
Object obj1 = con2.newInstance("张三",15,"湖北省武汉");
Person p1 = (Person)obj;    

//返回私有构造函数的对象
Constructor con3 =  c.getDeclaredConstructor(String.class);//不仅仅可以取私有的,所有的都可以取得
con3.setAccessible(true);
Object obj2 = con3.newInstance("ellen");
Person p2 = (Person)obj2;   

5.2 通过反射获取任意类的成员方法

Class c = Class.forName(path);//path:类的全路径

//获取自己包含父类的所有公共方法
Method[] methods1 = c.getMethods();

//获取自己的所有方法(没有父类的)
Method[] methods2 = c.getDeclaredMethods

Constructor con = c.getConstructor();
Object obj = con.newInstance();

//获取单个公共的方法
Method method3 = c.getMethod(methodName);//methodName:方法的名字
Method method4 = c.getMethod(methodName1,String.class,int.class)

methodName:"show"
method3:public void path.show()
method4:public void path.show(Stirng s,int i)

method3.invoke(obj);//调用obj对象的show方法
method4.invoke(obj,"ellen",22);//调用obj对象的show(String s,int i)方法

//methodName1:"getName"
Method method5 = c.getMethod(methodName1,String.class,int.class);
Object objString = method5.invoke("obj","hell0",100);//调用obj对象的public String getName(String s,int i)方法

//获取单个的私有方法(所有方法)
//methodName2:"run"
Method method6 = c.getDeclaredMethod(methodName2);
method6.setAccessible(true);//取得访问权限
method6.invoke(obj);//调用obj对象的private void run()方法

5.3 通过反射获取任意类的成员变量

Class  c = Class.forName(path);

//获取所有的公共的成员变量
Field[] fields1 = c.getFields();

//获取所有的成员变量
Field[] fields2 = c.getDeclaredFields();

Constructor con = c.getConstructor();
Object obj = con.newInstance;

//获取单个公共的成员变量
Field  addressField = c.getField("address");

String s = addressField.set(obj,"武汉");
syso(s);

//获取私有的成员变量(所有的)
Field idField = c.getDeclaredField("id");

idField.setAccessible(true);//取得访问权限
String id = idField.set(obj,"4201141490814810");
syso(id);

6.Android中反射的使用

1.通过原始的Java反射机制的方式调用资源。

2.Activity的启动过程中Activity的对象的创建。

没有更多推荐了,返回首页