java中的反射

1.什么是反射

简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 
那么就可以通过反射机制来获得类的所有信息。 

简单的来说就是两点,在运行期间:

1、对于任意一个类,都能够知道这个类的所有属性和方法

2、对于任意一个类,都能够调用它的任意一个属性和方法

2.反射的作用。

为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 
    静态编译:在编译时确定类型,绑定对象. 
    动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。 
    一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中,它的灵活性就表现的十分明显。

    其实我们学过的jdbc加载驱动,Class.forName("com.mysql.jdbc.Driver.class").newInstance();这就是反射,现在很多开框架都用到反射机制,hibernate、struts都是用反射机制实现的。 


    它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。 

3.反射的应用

下面具体看例子,从反射中我们能得到什么东西。

(1):Class和ClassLoader

 Class c=Class.forName("className");注明:className必须为类的全路径名,也就是得包含包名,比如:com.test.Test;
 c.getClass();//获取java.lang.Class的Class对象
 c.getClassLoader(); // 获取类的加载器
 c.getSuperclass(); // 获取父类Class对象
 c.getInterfaces() :// 获取类的接口列表,注意返回的是一个数组
 Object obj=c.newInstance();//创建对象的实例 

(2):Package

Package p = c.getPackage();
p.getName());// 获取包名
p.getImplementationTitle());//获取包标题
p.getImplementationVendor());//获取提供该实现的组织、供应商或公司的名称
p.getImplementationVersion());/ 获取该实现的版本
p.isSealed());// 获取包是否密封的

(3):Constructor

Class<?> c = Class.forName("com.test.Test");
Constructor<?>[] constructors = c.getConstructors();// 获取所有的构造函数
Constructor<?> constructor = c.getConstructor(String.class);// 获取指定参数列表的构造函数
constructor.getName()); // 获取构造函数名,没什么意义,肯定是和类同名
constructor.getModifiers()); // 获取以整数形式返回的此Constructor对象的Java语言修饰符,如public、static、final等
constructor.isAccessible()); // 获取该Constructor的访问权限
constructor.getParameterTypes()[0]); // 获取Constructor的参数类型,是个数组
constructor.isVarArgs()); // 获取此Constructor中是否带了可变数量的参数,即例如"String... str"类型的参数
TestRef r = (TestRef)constructor.newInstance("123"); // 根据指定的构造方法实例化出一个类的实例来,重要

(4):Method

Class<?> c = Class.forName("com.test.Test");
Method[] ms0 = c.getMethods();// 获取此类包括其父类中所有的public方法
Method md0 = c.getMethod("publicMethod", int.class, double.class, List.class);// 根据方法名和参数列表获取指定的public方法
Method[] ms1 = c.getDeclaredMethods();// 返回此类中所有的方法(无访问权限限制),但不包括继承的方法
Method md1 = c.getDeclaredMethod("privateMethod", new Class[0]);// 根据方法名和参数列表获取指定的任意访问权限的方法,但不包括继承的方法
md0.getName()); // 获取方法的名字
md0.isAccessible()); // 获取方法的访问属性
md0.isVarArgs()); // 获取方法是否带有可变数量的参数
md0.getReturnType()); // 获取方法的返回类型
md0.getParameterTypes()[0]//获取方法的参数类型,数组形式,注意一下和下面的方法的区别
md0.getGenericParameterTypes()[2]);//获取方法的参数化(带泛型)类型,数组形式
md0.invoke(r, 1, 2.2, new ArrayList<String>())// 反射调用方法,重要

(5):Field

Class<?> c = Class.forName("com.test.Test");
Field[] fs0=getFields();// 获取类中所有public字段,顺序即public的Field定义的顺序
Field f0 = c.getField("b"); )//根据变量名得到相应的public变量
Field[] fs1 = c.getDeclaredFields();// 获取类中任意访问权限的字段,顺序即所有Field定义的顺序
Field f1 = c.getDeclaredField("d");// 根据name获取类中一个任意访问权限的字段
f0.getName()); // 获取字段名
f0.getType()); // 获取类的类型
f0.getBoolean(r)); // 获取某个实例对象该Field的值,什么类型的Field就是getXXX(Object obj)
f0.getModifiers()); // 以整数形式返回此Field对象的Java语言修饰符,如public、static、final等
f0.isAccessible()); // 返回Field的访问权限,对private的Field赋值,必须要将accessible设置为true,如下

4.Modifier枚举值列表

Field、Constructor、Method中都有getModifiers()方法,返回的是表示此对象的Java语言修饰符,详细看下每个修饰符对应的枚举值:

 

也就是说如果一个方法是"public static final synchronized"的,那么这个方法的getModifiers()返回的应该是1 + 8 + 16 + 32 = 57,

 

转载地址:

http://www.cnblogs.com/xrq730/p/4862111.html

http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html

 

posted @ 2017-10-22 18:01  申公  阅读(292)  评论(0编辑  收藏  举报