java反射机制
反射机制:所谓的反射机制就是java谓言在行谓谓有一谓自谓的能力。通谓谓谓能力可运
以谓底的了解自身的情谓下一步的谓作做准谓。下面具介谓一下况体java的反射机制。谓里谓覆原谓你将来java的理解。
Java的反射机制的谓谓要借助于4个谓,class~Constructor~Field~Method~其中class代表的谓谓谓 象~Constructor,谓的造器谓象~构Field,谓的性谓象属~Method,谓的
谓象。通谓谓四谓象我谓可以粗略的看到一谓的各谓 成部分个个个。Class,程序行谓~运java运会运行谓系谓谓所有的谓象谓行行谓谓型的谓理。谓谓信息谓谓了每谓象所的谓~谓机通常使用行谓谓型信息谓谓正 的方法谓行;摘自,个属虚运确来
白皮谓,。但是谓些信息我谓谓得到~就要借助于怎啊class谓谓象了。在啊Object谓中定谓了getClass()方法。我 谓可以通谓谓方法谓得指定谓象的谓谓象。然后我谓通谓个
分析谓谓象就可以得到我谓要的信息了。个
比如,ArrayList arrayList;
Class clazz = arrayList.getClass();然后我谓理谓谓象来个clazz。
当然了Class谓具有多的方法~谓里重点和很将Constructor~Field~Method谓有谓系的方法。
Reflection 是 Java 程序谓谓谓言的特征之一~允谓行中的 它运Java 程序谓自身谓行谓谓~或者谓“自谓”~能直接操作程序的部性。并内属Java 的谓一能力在谓谓谓用中也谓用得不是多~但是人谓谓要想谓很个java有更加深入的了解谓是谓谓掌握的。个
1,谓谓谓,
reflection的工作机制
考谓下面谓谓谓的例子~谓我谓看看 个reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {try {
Class c = Class.forName(args[0]);Method m[] = c.getDeclaredMethods();for (int i = 0; i < m.length; i++)System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
按如下谓句谓行,
java DumpMethods java.util.ArrayList谓程序使用 个Class.forName 谓入指定的谓~然后谓用 getDeclaredMethods 来谓取谓谓中定谓了的方法列表。个java.lang.reflect.Methods 是用描述某谓中谓来个个方法的一谓。个
Java谓反射中的主要方法
谓于以下三谓谓件中的任何一谓谓 来-- 构数造函、字段和方法 -- java.lang.Class 提供四谓立的反射谓用~以不同的方式谓得信息。谓用都遵循一谓谓准格式。以下独来
是用于谓造函的一谓反射谓用,找构数
Constructor getConstructor(Class[] params) -- 谓得使用特殊的谓型的公共参数构造函~数
Constructor[] getConstructors() -- 谓得谓的所有公共造函构数
Constructor getDeclaredConstructor(Class[] params) -- 谓得使用特定谓型的参数构数造函(与接入谓谓无谓)
Constructor[] getDeclaredConstructors() -- 谓得谓的所有造函构数(与接入谓谓无谓)谓得字段信息的Class 反射谓用不同于那些用于接入造函的谓用~在谓型构数参数数谓中使用了字段名,
Field getField(String name) -- 谓得命名的公共字段
Field[] getFields() -- 谓得谓的所有公共字段
Field getDeclaredField(String name) -- 谓得谓明的命名的字段声
Field[] getDeclaredFields() -- 谓得谓明的所有字段声
用于谓得方法信息函,数
Method getMethod(String name, Class[] params) -- 使用特定的谓型~谓得参数命名的公共方法
Method[] getMethods() -- 谓得谓的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特的谓写参数型~谓得谓明的命名的方法声
Method[] getDeclaredMethods() -- 谓得谓明的所有方法声
使用 Reflection,
用于 reflection 的谓~如 Method~可以在 java.lang.relfect 包中到。使用谓些找谓的谓候必谓要遵循三步谓,第一步是谓得想操作的谓的 个你java.lang.Class 谓象。在行中的 运Java 程序中~用 java.lang.Class 谓描述谓和接口等。来
下面就是谓得一 个Class 谓象的方法之一,
Class c = Class.forName("java.lang.String");
谓谓句得到一 条个String 谓的谓谓象。谓有一谓方法~如下面的谓句,另
Class c = int.class;
或者
Class c = Integer.TYPE;
它装谓可谓得基本谓型的谓信息。其中后一谓方法中谓谓的是基本谓型的封谓 (如 Intege ) 中谓先定谓好的 TYPE 字段。
第二步是谓用谓如 getDeclaredMethods 的方法~以取得谓谓中定谓的所有方法的列表。
一旦取得谓信息~就可以谓行第三步了使用 个——reflection API 来操作谓些信息~如下面谓段代谓,
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();System.out.println(m[0].toString());它将以文本方式打印出 String 中定谓的第一方法的原型。个
谓理谓象,
a.谓建一个Class谓象
b.通谓getField 谓建一个Field谓象
c.谓用Field.getXXX(Object)方法(XXX是Int,Float等~如果是谓象就省略~Object是指谓例).
例如,
import java.lang.reflect.*;
import java.awt.*;
class SampleGet {
public static void main(String[] args) {Rectangle r = new Rectangle(100, 325);printHeight(r);
}
static void printHeight(Rectangle r) {Field heightField;
Integer heightValue;
Class c = r.getClass();
try {
heightField = c.getField("height");heightValue = (Integer) heightField.get(r);System.out.println("Height: " + heightValue.toString());
} catch (NoSuchFieldException e) {System.out.println(e);
} catch (SecurityException e) {System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
}
}
}
安全性和反射,
在谓理反射谓安全性是一谓谓谓的谓谓。反射谓常由架型代谓使用~由于谓一点~我谓个框
可能希望架能谓全面接入代谓~无需考谓常谓的接入限制。但是~在其情下框它况~不受控制的接入谓谓重的安全性谓谓~例如谓代谓在不谓得信任的代谓共享的谓境会来当
中行谓。运
由于谓些互相矛盾的需求~Java谓程谓言定谓一谓多谓谓方法谓理反射的安全性。基来
本模式是谓反射谓施谓用于源代谓接入相同的限制,与
从任意位置到谓公共谓件的接入
谓自身外部无任何到私有谓件的接入
受保谓和打包;缺省接入,谓件的有限接入
不谓至少有些谓候~谓谓谓些限制谓有一谓谓谓的方法。我谓可以在我谓所的谓中~谓展一写个普通的基本谓 java.lang.reflect.AccessibleObject 谓。谓谓定谓了一谓个
setAccessible方法~使我谓能谓谓或谓谓谓谓些谓中其中一谓的谓例的接入谓谓。唯一启个
的谓谓在于如果使用了安全性管理 器~谓谓正在谓谓接入谓谓的代谓是否谓可了谓谓做它将。如果未谓可~安全性管理器抛出一例外。个
下面是一段程序~在TwoString 谓的一谓例上使用反射谓示安全性正在行,个来运
public class ReflectSecurity {public static void main(String[] args) {try {
TwoString ts = new TwoString("a", "b");Field field = clas.getDeclaredField("m_s1");
// field.setAccessible(true);System.out.println("Retrieved value is " +field.get(inst));
} catch (Exception ex) {
ex.printStackTrace(System.out);}
}
}
如果我谓谓谓谓一程序谓~不使用任何特定直接命令行行~在参数从运它将field .get(inst)谓用中抛出一个IllegalAccessException异常。如果我谓不注谓 field.setAccessible(true)代谓行~那谓重新谓谓重新行谓代谓~谓谓成功。最后并运它将~如果我谓在命令行添加了JVM参数 -Djava.security.manager以谓谓安全性管理器~它将仍然不能通谓谓谓~除非我谓定谓了ReflectSecurity谓的谓可谓 限。反射性能,;谓谓谓人的,啊
反射是一谓强大的工具~但也存在一些不足。一主要的缺点是谓性能有影。个响
使用反射基本上是一谓解谓操作~我谓可以告谓JVM~我谓希望做什谓且谓足我谓并它的要求。谓谓操作谓是慢于只直接谓行相同的操作。
下面的程序是字段接入性能谓谓的一例子~包括基本的谓谓方法。每谓方法谓谓字段个
接入的一谓形式 -- accessSame 与同一谓象的成谓字段谓作~accessOther 使用可直接接入的一谓象的字段~另accessReflection 使用可通谓反射接入的一谓象的另字段。在每谓情下~方法谓行相同的谓算 况-- 循谓中谓谓的加/乘谓序。程序如下,
public int accessSame(int loops) {m_value = 0;
for (int index = 0; index < loops; index++) {
m_value = (m_value + ADDITIVE_VALUE) *MULTIPLIER_VALUE;
}
return m_value;
}
public int acces
sReference(int loops) {
TimingClass timing = new TimingClass();for (int index = 0; index < loops; index++) {timing.m_value = (timing.m_value + ADDITIVE_VALUE) *MULTIPLIER_VALUE;
}
return timing.m_value;
}
public int accessReflection(int loops) throws Exception {
TimingClass timing = new TimingClass();try {
Field field = TimingClass.class.
getDeclaredField("m_value");
for (int index = 0; index < loops; index++) {int value = (field.getInt(timing) +
ADDITIVE_VALUE) * MULTIPLIER_VALUE;
field.setInt(timing, value);
}
return timing.m_value;
} catch (Exception ex) {
System.out.println("Error using reflection");throw ex;
}
}
在上面的例子中~谓谓程序重谓谓用每谓方法~使用一大循谓~而平均多次谓用个数从
的谓谓衡量谓果。平均谓中不包括每谓方法第一次谓用的谓谓~因此初始化谓谓不是谓果中的一因素。下面的谓楚的向我谓展示了每谓方法字段接入的谓谓,个清
谓 1,字段接入谓谓 ,
我谓可以看出,在前副谓中两(Sun JVM)~使用反射的谓行谓谓超谓使用直接接入的1000倍以上。通谓比谓~IBM JVM可能稍好一些~但反射方法仍需要比其旧它方法谓700倍以上的谓谓。任何JVM上其谓方法之谓谓谓方面无任何谓它两异著差~但IBM JVM几乎比Sun JVM快一倍。最有可能的是谓谓差异反映了Sun Hot Spot JVM的谓谓谓化~在谓谓基准方面表谓得它很糕糟。反射性能是Sun谓谓1.4 JVM谓谓注的一方面~在反射方法谓用谓果中谓示。在谓谓操作的性能方面~个它Sun 1.4.1 JVM谓示了比1.3.1版本大的很改谓。
如果谓谓谓建使用反射的谓象谓了谓写会况异似的谓谓谓谓程序~我谓谓谓谓谓情下的差不象字段和方法谓用情下那谓谓况著。使用newInstance()谓 用谓建一谓谓的个
java.lang.Object谓例耗用的谓谓大谓是在Sun 1.3.1 JVM上使用new Object()的12倍~是在IBM 1.4.0 JVM的四倍~只是Sun 1.4.1 JVM上的部。使用两
Array.newInstance(type, size)谓建一谓个数耗用的谓谓是任何谓谓的JVM上使用new type[size]的倍~两随数异随着谓大小的增加~差逐步谓小。着jdk6.0的推出~反射机制的性能也有了大的提很升。期待中….
谓谓,
Java谓言反射提供一谓谓谓谓接程序谓件的多功能方法。允谓程序谓建和控制任何谓它
的谓象(根据安全性限制)~无需提前硬谓谓目谓谓。谓些特性使得反射 特谓适用于谓建以非常普通的方式谓象谓作的谓。例如~反射谓常在与数持谓存谓谓象谓据谓、XML或其外部格式的架中使用。它框Java reflection 非常有用~使谓和它数构据谓能按名谓谓谓称并运索相谓信息~允谓在行着的程序中操作谓些信息。Java 的谓一特性非常强大~且是其一些常用谓言~如 并它C、C++、Fortran 或者 Pascal 等都不具谓的。
但反射有缺点。第一是性能谓谓。用于字段和方法接入谓反射要谓慢于直接两个个
代谓。性能谓谓的程度取于程序中是如何使用反射的。如果作谓程序行中相决它运 谓少很将会个即坏况涉及的部分~谓慢的性能不是一谓谓。使谓谓中最情下的谓谓谓谓示的反射操作只耗用几微秒。谓反射在性能谓谓的谓用的核心谓谓中使用谓性 能谓谓才谓得至谓重要。
谓多谓用中更谓重的一缺点是使用反射模个会内糊程序部谓谓要谓生的事情。程序人谓希望在源代谓中看到程序的谓谓~反射等谓谓了源代谓的技谓谓谓谓谓谓 谓。反射代谓比会来
相谓的直接代谓更谓谓~正如性能比谓的代谓谓例中看到的一谓。解谓些谓谓的最决佳
是保守地使用反射谓在可以正——它真灵——增加活性的地方 谓谓其在目谓谓中的使用。一下是谓谓各部分的例子,个
具的谓用,体
1、 模仿instanceof 运号算符
class A {}
public class instance1 {
public static void main(String args[]){
try {
Class cls = Class.forName("A");boolean b1
= cls.isInstance(new Integer(37));System.out.println(b1);
boolean b2 = cls.isInstance(new A());System.out.println(b2);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
2、 在谓中谓指定的方法~同谓谓取谓方法的列表~例外和找参数返回谓import java.lang.reflect.*;public class method1 {
private int f1(
Object p, int x) throws NullPointerException
{
if (p == null)
throw new NullPointerException();
return x;
}
public static void main(String args[]){
try {
Class cls = Class.forName("method1");Method methlist[]
= cls.getDeclaredMethods();
for (int i = 0; i < methlist.length;i++)
Method m = methlist[i];
System.out.println("name
= " + m.getName());
System.out.println("decl class = " +m.getDeclaringClass());
Class pvec[] = m.getParameterTypes();for (int j = 0; j < pvec.length; j++)System.out.println("
param #" + j + " " + pvec[j]);Class evec[] = m.getExceptionTypes();for (int j = 0; j < evec.length; j++)System.out.println("exc #" + j+ " " + evec[j]);
System.out.println("return type = " +m.getReturnType());
System.out.println("-----");
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
3、 谓取谓的造函信息~基本上谓取方法的方式相同构数与
import java.lang.reflect.*;
public class constructor1 {
public constructor1()
{
}
protected constructor1(int i, double d){
}
public static void main(String args[]){
try {
Class cls = Class.forName("constructor1");Constructor ctorlist[]
= cls.getDeclaredConstructors();for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name
= " + ct.getName());
System.out.println("decl class = " +ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();for (int j = 0; j < pvec.length; j++)System.out.println("param #"
+ j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();for (int j = 0; j < evec.length; j++)System.out.println(
"exc #" + j + " " + evec[j]);
System.out.println("-----");
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
4、 谓取谓中的各个数称号据成谓谓象~包括名。谓型和谓谓修谓符
import java.lang.reflect.*;
public class field1 {
private double d;
public static final int i = 37;
String s = "testing";
public static void main(String args[]){
try {
Class cls = Class.forName("field1");Field fieldlist[]
= cls.getDeclaredFields();
for (int i
= 0; i < fieldlist.length; i++) {Field fld = fieldlist[i];
System.out.println("name
= " + fld.getName());
System.out.println("decl class = " +fld.getDeclaringClass());
System.out.println("type
= " + fld.getType());
int mod = fld.getModifiers();System.out.println("modifiers = " +Modifier.toString(mod));
System.out.println("-----");}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
5、 通谓使用方法的名字谓用方法
import java.lang.reflect.*;public class method2 {
public int add(int a, int b){
return a + b;
}
public static void main(String args[]){
try {
Class cls = Class.forName("method2");Class partypes[] = new Class[2];partypes[0] = Integer.TYPE;partypes[1] = Integer.TYPE;Method meth = cls.getMethod("add", partypes);
method2 methobj = new method2();Object arglist[] = new Object[2];arglist[0] = new Integer(37);arglist[1] = new Integer(47);Object retobj
= meth.invoke(methobj, arglist);Integer retval = (Integer)retobj;
System.out.println(retval.intValue());}
catch (Throwable e) {
System.err.println(e);
}
}
}
6、 谓建新的谓象
import java.lang.reflect.*;public class constructor2 {public constructor2()
{
}
public constructor2(int a, int b){
System.out.println(
"a = " + a + " b = " + b);}
public static void main(String args[]){
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];partypes[0] = Integer.TYPE;partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);Object arglist[] = new Object[2];arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);}
catch (Throwable e) {
System.err.println(e);
}
}
}
7、 谓更谓谓例中的数据的谓
import java.lang.reflect.*;
public class field2 {
public double d;
public static void main(String args[]){
try {
Class cls = Class.forName("field2");Field fld = cls.getField("d");field2 f2obj = new field2();
System.out.println("d = " + f2obj.d);fld.setDouble(f2obj, 12.34);
System.out.println("d = " + f2obj.d);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
使用反射谓建可重用代谓,
1、 谓象工厂
Object factory(String p) {
Class c;
Object o=null;
try {
c = Class.forName(p);// get class defo = c.newInstance(); // make a new one} catch (Exception e) {
System.err.println("Can't make a " + p);}
return o;
}
public class ObjectFoundry {public static Object factory(String p)throws ClassNotFoundException,InstantiationException,
IllegalAccessException {
Class c = Class.forName(p);
Object o = c.newInstance();return o;
}
}
2、 谓谓谓谓谓象的身~份替代instanceof
public static boolean
isKindOf(Object obj, String type)throws ClassNotFoundException {// get the class def for obj and typeClass c = obj.getClass();
Class tClass = Class.forName(type);while ( c!=null ) {
if ( c==tClass ) return true;c = c.getSuperclass();
}
return false;
}