Java反射

http://www.importnew.com/20339.html

Java 反射是 Java 被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时通过 Reflection APIs取得任何一个已知名称的class 的内部信息,包括其 modifiers( 诸如 public, static 等 )、superclass(例如 Object)、 实现之 interfaces(例如 Cloneable),也包括 fields 和 methods的所有信息,并可于运行时改变 fields 内容或唤起 methods。

Java 反射机制容许程序在运行时加载、探知、使用编译期间完全未知的 classes。 换言之,Java 可以加载一个运行时才得知名称的 class,获得其完整结构。

ava 反射相关的 API 在包 java.lang.reflect 中,JDK 1.6.0的 reflect 包如下图:

Member 接口 该接口可以获取有关类成员(域或者方法)后者构造函数的信息。

AccessibleObject 类

该类是域(field)对象、方法(method)对象、构造函数(constructor)对象 的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控 制检查的能力。

Array 类    提供动态地生成和访问 JAVA 数组的方法。

Constructor 类    提供一个类的构造函数的信息以及访问类的构造函数的接口。

Field 类    提供一个类的域的信息以及访问类的域的接口。

Method 类    提供一个类的方法的信息以及访问类的方法的接口。

Modifier类    提供了 static 方法和常量,对类和成员访问修饰符进行解码。

Proxy 类    提供动态地生成代理类和类实例的静态方法。

JAVA 反射机制提供了什么功能

Java 反射机制提供如下功能:

1. 在运行时判断任意一个对象所属的类

2. 在运行时构造任意一个类的对象

3. 在运行时判段任意一个类所具有的成员变量和方法

4. 在运行时调用任一个对象的方法

5. 在运行时创建新类对象

在使用 Java 的反射功能时,基本首先都要获取类的 Class 对象,再通过 Class 对象获取 其他的对象。


源码分析:

1、获取类的 Class 对象

.class getClass()

2、获取类的 Fields

可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。JAVA 的 Class类提供了几个方法获取类的属性。

public Field getField(String name)

返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段

public Field[] getFields()

返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段

public Field getDeclared Field(String name)

返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段

public Field[] getDeclared Fields()

返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或 接口所声明的所有字段

Tips:

getFields返回的是申明为 public的属性,包括父类中定义,

getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。

3、获取类的 Method

通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法


public Method getMethod(String name, Class... parameterTy pes)

返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法;

public Method[] getMethods()

返回一个包含某些 Method 对象的数组,这些对象反映此Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那 些的类或接口)的公共 member 方法;

public Method getDeclaredMethod(Stringname,Class<?>...parameterTy pes)

返回一个 Method 对象,该对象反映此Class 对象所表示的类或接口的指定已声明方法;

public Method[] getDeclaredMethods()

返回 Method对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

4、获取类的 Constructor通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例Class类提供了几个方法获取类的构造器。

public Constructor< T>

返回一个 Constructor 对象,它反映此 Class对象所表示的类的指定 公共构造方法

...

5、新建类的实例

通过反射机制创建新类的实例,有几种方法可以创建新类的实例,调用无自变量

①、调用类的 Class对象的 newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败.

Class classType = ExtendType.class; Object inst = classType.newInstance(); System.out.println(inst);

Tips:在调用内部类的newInstance时会报如下错误,将内部类改为static就可以在main方法中成功实例化。背景:public class Test{} 里面定义了内部类class SubTest extends Test{}

java.lang.InstantiationException: com.meki.play.framework.design.Test$SubTest
    at java.lang.Class.newInstance(Class.java:427)
    at com.meki.play.framework.design.Test.main(Test.java:129)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NoSuchMethodException: com.meki.play.framework.design.Test$SubTest.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 6 more


②、调用默认 Constructor 对象的 newInstance 方法

Constructor  constructor1 = classType.getConstructor();

Object inst = constructor1.newInstance(); System.out.println(inst);

③、调用带参数 Constructor 对象的 newInstance 方法

Constructor constructor2 =

classType.getDeclaredConstructor(int.class, String.class);

Object inst = constructor2.newInstance(1, "123"); System.out.println(inst);


反射的用途

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.This is a relatively advanced feature and should be used only by developers who have a strong grasp of the fundamentals of the language.With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible.

反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。这是一个相对高级的特性,只有那些语言基础非常扎实的开发者才应该使用它。如果能把这句警示时刻放在心里,那么反射机制就会成为一项强大的技术,可以让应用程序做一些几乎不可能做到的事情。

反射的缺点

Reflection is powerful, but should not be used indiscriminately. If it is possible to performan operation without using reflection, then it is preferable to avoid using it. The following concerns should be kept in mind when accessing code via reflection.

尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。

在我们使用反射技术时,下面几条内容应该牢记于心:

性能第一 

Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed.Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently inperformance-sensitive applications.

反射包括了一些动态类型,所以 JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。

安全限制 

Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有

安全限制的环境中运行,如 Applet,那么这就是个问题了。

内部暴露 

Since reflection allows code to perform operations that would be illegal in non-reflective code, such  as accessing private fields  and methods, the  use of reflection  can  result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgradesof the platform.

由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

业务思想

JAVA中反射机制很实用。在不断地项目实战中,大家或许才体会到反射的真正强大之处

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容

  • 对于Java反射,平常工作中虽然经常用到,但一直以来都没有系统总结过,所以趁着目前有空总结一下,加深一下理解。 如...
    西华子阅读 1,338评论 0 10
  • 问题: 在运行时,对一个JAVA类,能否知道属性和方法;能否调用它的任意方法? 答案是可以的,JAVA提供一种反射...
    糖宝_阅读 759评论 0 1
  • 首发于公众号:专业电影评论 专业影评 @TOC java反射机制的应用器 开发的时候有时候会碰到这样的情况,...
    专业电影评论阅读 307评论 0 1
  • 类加载机制 1 什么是反射 Java反射机制是在运行状态中对于任意一个类,都能知道这个类的所以属性和方法;对于任何...
    凯玲之恋阅读 13,815评论 3 28
  • 感觉又经历一次生死…… 现在看表快7点,我不知道我凌晨几点开始疼的,反正巨疼至少得有4、50分钟。 疼的感觉即将休...
    张粤丹阅读 102评论 0 0