java reflection学习
编程技术  /  houtizong 发布于 3年前   53
参考:
【1】http://dev.csdn.net/article/49/49876.shtm
【2】http://tutorials.jenkov.com/java-reflection/index.html
Java reflection
什么是java反射机制? java机制能干什么?
从理论上说,java reflection 就是对运行中的class进行“自审”。允许程序对运行中的类、接口等重的属性、方法进行检测。常用的地方有:java bean、Hibernate的数据库映射等。
java reflection的包“java.lang.reflect”。
1.获取操作类的java.lang.Class对象:
Class c = Class.forName("java.lang.String"); Class c = int.class; Class c = Integer.TYPE;
2.获取诸如getDeclearedMethods方法,以取得该类中定义的所有方法的列表。
Class c = Class.forName("java.lang.String"); Method m[] = c.getDeclearedMethods();
3.操作这些信息
System.out.println(m[0].toString());
常用操作:
1.获取类的methods
Class c = Class.forName("constructor1");Method[] m[] = c.getDeclearedMethods();
getDeclearedMethods()://获取类中所有方法。
getMethods()://还可以获取继承来的各个方法信息。
2.获取构造器
Class cls = Class.forName("constructor1"); Constructor ctorlist[] = cls.getDeclaredConstructors();
3.获取所有属性
Class cls = Class.forName("reflection.field1"); Field fieldlist[] = cls.getDeclaredFields();
4.根据方法的名称来执行方法
import java.lang.reflect.Method;/* * 根据方法的名称来执行方法 */public class Method2 { public int add(int a, int b) { return a + b; } public static void main(String args[]) { try { Class cls = Class.forName("reflection.method2"); // 用于查找一个具有两个整型参数且名为 add 的方法 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); } }}
5.执行构造器,创建新的对象实例
package reflection;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("reflection.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); } }}
6.改变字段(域)的值
reflection 的还有一个用处就是改变对象数据字段的值。reflection 可以从正在运行的程序中根据名称找到对象的字段并改变它,下面的例子可以说明这一点:
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); } }}
这个例子中,字段 d 的值被变为了 12.34。
7.使用数组
创建的操作数组。数组在 Java 语言中是一种特殊的类类型,一个数组的引用可以赋给 Object 引用。观察下面的例子看看数组是怎么工作的:
import java.lang.reflect.*;public class array1 { public static void main(String args[]) { try { Class cls = Class.forName("java.lang.String"); Object arr = Array.newInstance(cls, 10); Array.set(arr, 5, "this is a test"); String s = (String) Array.get(arr, 5); System.out.println(s); } catch (Throwable e) { System.err.println(e); } }}
例中创建了 10 个单位长度的 String 数组,为第 5 个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来。
下面这段代码提供了一个更复杂的例子:
import java.lang.reflect.*;public class array2 { public static void main(String args[]) { int dims[] = new int[]{5, 10, 15}; Object arr = Array.newInstance(Integer.TYPE, dims); Object arrobj = Array.get(arr, 3); Class cls = arrobj.getClass().getComponentType(); System.out.println(cls); arrobj = Array.get(arrobj, 5); Array.setInt(arrobj, 10, 37); int arrcast[][][] = (int[][][]) arr; System.out.println(arrcast[3][5][10]); }}
例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后,arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素,即长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。
注意创建数组时的类型是动态的,在编译时并不知道其类型。
------------class--------
8.获取类名
// 获取类的全名(包名+类名)Class aClass = MyObject.class;String className = aClass.getName();// 获取类名(不包含包名)Class aClass = MyObject.class;String simpleClassName = aClass.getSimpleName();
9.获取修饰符
int mod = *.getModifiers();Modifier.toString(mod));
10.获取包信息
Package package = aClass.getPackage();
11.获取父类
Class superclass = aClass.getSuperclass();
12.获取实现的接口
Class[] interfaces = aClass.getInterfaces();
13.others
Constructor[] constructors = aClass.getConstructors();Method[] method = aClass.getMethods(); Method[] method = aClass.getFields();
-------Constructor ------------
14.获取构造方法
Class aClass = ...//obtain class objectConstructor[] constructors = aClass.getConstructors();// 如果你已经知道构造方法的参数,也可以用以下代码获取具体方法Class aClass = ...//obtain class objectConstructor constructor = aClass.getConstructor(new Class[]{String.class});
15.获取构造方法的参数信息
Constructor constructor = ... // obtain constructor - see aboveClass[] parameterTypes = constructor.getParameterTypes();
16.实例化对象
//get constructor that takes a String as argumentConstructor constructor = MyObject.class.getConstructor(String.class);MyObject myObject = (MyObject) constructor.newInstance("constructor-arg1");// 实际参数列表
---------Fileds------------------
16.获取属性信息
Class aClass = ...//obtain class objectField[] methods = aClass.getFields();// 如果你知道属性名字Class aClass = MyObject.classField field = aClass.getField("someField");
17.获取属性名字
Field field = ... //obtain field objectString fieldName = field.getName();
18.获取属性类型
Field field = aClass.getField("someField");Object fieldType = field.getType();
19.获取或设置属性值
Class aClass = MyObject.classField field = aClass.getField("someField");MyObject objectInstance = new MyObject();// 获取属性值Object value = field.get(objectInstance);// 设置属性值field.set(objetInstance, value);
------------Methods-------------
20.获取方法
Class aClass = ...//obtain class objectMethod[] methods = aClass.getMethods();// 获取具体的某一方法,有参数Class aClass = ...//obtain class objectMethod method = aClass.getMethod("doSomething", new Class[]{String.class});// 获取具体的某一方法,无参数Class aClass = ...//obtain class objectMethod method = aClass.getMethod("doSomething", null);
21.获取方法的参数或返回类型
Method method = ... // obtain method - see aboveClass[] parameterTypes = method.getParameterTypes();Class returnType = method.getReturnType();
22.使用method对象执行方法
//get method that takes a String as argumentMethod method = MyObject.class.getMethod("doSomething", String.class);Object returnValue = method.invoke(null, "parameter-value1");
----------gets & sets----------------
23.set/get方法
public static void printGettersSetters(Class aClass){ Method[] methods = aClass.getMethods(); for(Method method : methods){ if(isGetter(method)) System.out.println("getter: " + method); if(isSetter(method)) System.out.println("setter: " + method); }}public static boolean isGetter(Method method){ if(!method.getName().startsWith("get")) return false; if(method.getParameterTypes().length != 0) return false; if(void.class.equals(method.getReturnType()) return false; return true;}public static boolean isSetter(Method method){ if(!method.getName().startsWith("set")) return false; if(method.getParameterTypes().length != 1) return false; return true;}
----------访问私有属性(private fileds)---------------
24.访问私有属性
Class.getField(String name) 和 Class.getFields() 只能获取public的属性;
如果想获取私有属性,你需要使用:Class.getDeclaredField(String name) 或 Class.getDeclaredFields()
一般来说,一个类的私有属性在类之外是不能访问的,可通过java反射机制,却能够做到这一点。
示例代码:
类:
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; }}
私有属性访问代码
PrivateObject privateObject = new PrivateObject("The Private Value");Field privateStringField = PrivateObject.class. getDeclaredField("privateString");privateStringField.setAccessible(true);// 将该属性设置为可见// 你可以访问私有属性了,呵呵String fieldValue = (String) privateStringField.get(privateObject);System.out.println("fieldValue = " + fieldValue);
-----------access private methods---------------
25.和上一个比较类似
类:
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } private String getPrivateString(){ return this.privateString; }}
代码:
PrivateObject privateObject = new PrivateObject("The Private Value");Method privateStringMethod = PrivateObject.class. getDeclaredMethod("getPrivateString", null);privateStringMethod.setAccessible(true);String returnValue = (String) privateStringMethod.invoke(privateObject, null); System.out.println("returnValue = " + returnValue);
---------------Array---------------------
26.创建Array
创建一个int[3],第一个参数类型,第二个参数大小
int[] intArray = (int[]) Array.newInstance(int.class, 3);
27.访问数组
int[] intArray = (int[]) Array.newInstance(int.class, 3);Array.set(intArray, 0, 123);Array.set(intArray, 1, 456);Array.set(intArray, 2, 789);System.out.println("intArray[0] = " + Array.get(intArray, 0));System.out.println("intArray[1] = " + Array.get(intArray, 1));System.out.println("intArray[2] = " + Array.get(intArray, 2));
--------------others----------------------
另外java反射机制还可以访问:注释Annotations、泛型Generics、代理Proxies什么的。。。。。。。
因为太晚了缘故 暂时到这,以后再补充吧
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接