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