文档章节

【54】Java反射机制剖析

fengsehng
 fengsehng
发布于 2016/11/09 09:15
字数 1762
阅读 0
收藏 0

java反射机制:

1.指的是可以于运行时加载,探知和使用编译期间完全未知的类.

2.程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;

3.加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射。

4.每个类被加载进入内存之后,系统就会为该类生成一个对应的java.lang.Class对象,通过该Class对象就可以访问到JVM中的这个类.

静态加载类和动态加载类的概念区分:

这里写图片描述

与反射有关的类包.

java.lang.reflect.*;和java.lang.Class;

Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class。即每一个类型,在Class中都有一个Class对象跟它对应.Class 没有公共构造方法。注意不是没有,是没有公共的.

从Class中获取信息

这里写图片描述

如何获得Class对象

1.针对每一个对象.getCalss(),可以得到对应的Class.

2.Class.forName(String),String的写法:包名.类名.就会创建包名.类名对应的那个对象

注:1.2只适用于引用类型

3.对于基本类型:封装类.TYPE代表了对应的基本类型的Class对象.Integer.TYPE对应的是int的Class对象
注:3只适用于基本类型

4.类型,Class。<第4种是通用的.>
上面的4种方法,只有方法2是动态的,只要换一个包就可以了.它具有动态潜质.所以真正意义的想体现动态编程只能使用方法2.

每种类型的Class对象只有一个,即他们的地址只有一个,但是不同类型是不同的.所以下面的打印结果都为true.

//对与引用类型
Class c1 = "".getClass();
Class c2 =     Class.forName("java.lang.String");
Class c3 = String.class;
System.out.println(c1 ==c2);//true
//对于基本类型
Class num1 = Integer.TYPE;
Class num2 = int.class;
System.out.println(num1 == num2);//true

反射获取类中的成员的相关方法

[获取构造<根据参数类型>]使用时一般用不带declared的

Constructor<T> getConstructor(Class<?>... parameterTypes) 
      返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 
 Constructor<?>[] getConstructors() 
      返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 
 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 
      返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 
 Constructor<?>[] getDeclaredConstructors() 
      返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。

[获取属性<根据属性名>]使用时一般用是带declared的,因为属性一般都是私有的

Field getField(String name) 
      返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 
 Field[] getFields() 
      返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 
 Field getDeclaredField(String name) 
      返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 
 Field[] getDeclaredFields() 
      返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

[获取方法<方法名加上参数类型>]使用时一般用不带declared的

Method getMethod(String name, Class<?>... parameterTypes) 
      返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 
 Method[] getMethods() 
      返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 
 Method getDeclaredMethod(String name, Class<?>... parameterTypes) 
      返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 
 Method[] getDeclaredMethods() 
      返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 
 T newInstance() 
      创建此 Class 对象所表示的类的一个新实例。 <new Instance()可以动态的创建对象>
 String toString() 
      将对象转换为字符串。

注意:

new Instance()调用的是无参构造,如果该类没有无参构造方法,则newInstance()会产生异常.有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西.因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的.

实例模拟反射获取类中的相关属性和方法

利用反射对属性赋值

Field中的方法
Object get(Object obj)
返回指定对象上此 Field 表示的字段的值。
Field f = c.getXXField(属性名);
值 = f.get(对象);
void set(Object obj, Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
f.set(对象,值);
Class

    Class c = Student.class;
    Object obj  = c.newInstance();            //创建Student类的对象
    Field f = c.getDeclaredField("name");        //获取name属性
    f.setAccessible(true);                    //设置私有可以访问.
    f.set(obj, "zhangsan");
    System.out.println(f.get(obj));             //获取obj的name属性的值.

利用反射调用构造

对于构造真正调用是在调用newInstance()方法时.

Class c = Class.forName("com.clazz.reflect.Student");
    Constructor con = c.getConstructor(); //没有执行构造,
    Object cObj = c.getConstructor().newInstance();//调用无参的构造方法
    Constructor conAll = c.getConstructor(int.class,String.class,int.class);
    Object caobj = conAll.newInstance(1001,"zjamgs",234235);//调用含参的构造方法.
    System.out.println(caobj); //打印输出

利用反射调用方法

对象.方法名(值1,2,3);
Method m = c.getMethoed(方法名,参数类型…);
m.invoke(对象,方法调用的参数 )如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

Class c = Class.forName("com.clazz.reflect.Student");
    Object obj = c.newInstance(); //创建Sutdent对象.
    Method msetName = c.getMethod("setName", String.class);//obj无须转换类型
    msetName.invoke(obj, "zhangsan");//调用方法setName, 并传参.
    Method msetId = c.getMethod("setId", int.class);
    msetId.invoke(obj, 409090202);
    System.out.println(obj);

我的微信二维码如下,欢迎交流讨论

这里写图片描述

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

这里写图片描述

参考:

http://www.cnblogs.com/dennisit/archive/2013/02/26/2933508.html
http://blog.csdn.net/coder_pig/article/details/44784399
http://www.codeceo.com/article/java-reflector-usage.html

© 著作权归作者所有

共有 人打赏支持
fengsehng
粉丝 4
博文 284
码字总数 214494
作品 0
朝阳
程序员
私信 提问
阿里高级Java面试题(首发,70道,带详细答案)

整理的70道阿里的Java面试题,都来挑战一下,看看自己有多厉害。下面题目都带超详细的解答,详情见底部。 1、java事件机制包括哪三个部分?分别介绍。 2、为什么要使用线程池? 3、线程池有什...

java技术栈
2017/11/11
0
0
ButterKnife源码剖析

转载于:[http://blog.csdn.net/chenkai19920410/article/details/51020151] ButterKnife是Jake Wharton大神写开源框架。 项目托管地址: https://github.com/JakeWharton/butterknife。   ......

双鱼大猫
2016/12/16
0
0
最最最常见的Java面试题总结——第二周

String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性   String类中使用字符数组:保存字符串,所以String对象是...

Amsour丶
08/13
0
0
Android 4.4(KK)中利用APP打开关闭数据流量

在Android 4.4中,在app中打开或关闭数据流量 如果有这方面需求可以参考。 思路 利用JAVA的反射机制(Reflection),来调用CONNECTIVITY_SERVICE完成相关操作。 关于JAVA的反射机制,可以参考...

W_X
2014/12/17
0
4
云妹总结了一些最最最常见的Java面试题供大家参考

云妹导读:String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性 String类中使用字符数组:private final cha...

阿里云科技快讯
08/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day152-2018-11-19-英语流利阅读-待学习

外媒看吴亦凡刷榜事件 Lala 2018-11-19 1.今日导读 近日,吴亦凡的专辑在国外陷入了刷榜风波,他的新专辑霸占了单曲榜前三名,并且前十名他占据了七席,力压美国乐坛巨星 Lady Gaga 和 A 妹,...

飞鱼说编程
37分钟前
9
0
开源 java CMS - FreeCMS2.8 微信管理 群发图文消息

项目地址:http://www.freeteam.cn/ 群发图文消息 管理员可以在这里群发图文消息 此列表只提取已审核并且带信息图片的数据! 选择需要群发的消息,点击“群发图文消息”按钮。 微信的限定: ...

freeteam
46分钟前
1
0
Beautiful Soup

定义 Python中的一个库,主要用于从网页爬取数据; 安装 pip install beautifulsoup4 四大对象 Beautiful Soup将复杂的HTML文档转换成树形结构,树中的每个节点都是Python对象,对象可归纳为...

村雨1943
57分钟前
5
0
Visual Studio 昨日发布新版本:增加实时同步编程、共同调试

多名开发者可以在同一个项目中编程,在编写代码和调试代码时只需发送一个 URL 网址,就能邀请他人参与协作,而且无需重新配置开发环境和安装任何附加包。该服务支持 Windows、Mac 与 Linux ...

linuxCool
今天
8
0
发现一种不错的学习方法

这是在《软技能,代码之外的生存之道》所看到的一种学习方法,感觉这个理念不错,分享出来,共勉。 我的「十步学习法」 多年以来,我都承受着巨大的压力:快速学习新技术、新编程语言、新框架...

firepation
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部