Java 反射API

一、Java反射样例

设置任意对象的属性值的JavaScirpt实现

function invokeSetter(obj, property,value){
  var funcName = "set" + property.subString(0,1).toUpperCase() + property.substring(1);
  obj[funcName](value);
}
var obj = {
       value : 0 ,
      setVale: function(val) { this.value = val; } 
};
invokeSetter(obj, "value", 5);
通过Java反射API 实现同样功能,假设java中的属性都有setter和getter。

public static void invokeSetter(Object obj, String field, Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  String methodName = "set" + field.substring(0, 1).toUpperCase() + field.substring(1);
  Class<?> clazz = obj.getClass();
  Method = method = clazz.getMethod(methodName, value.getClass());
  method.invoke(obj, value);
}
常用场景:

1、Servlet中的HTTP请求的参数值来填充 领域对象(springMVC 中的 POJO)

2、数据库操作 从SQL回来的结构填充到领域对象。


二、获取构造方法

class对象的对应方法:

getConstructors获取所有公开的构造方法列表

getConstructor 根据参数获取公开的构造方法。

getDeclaredConstructors 获取声明的构造方法列表

getDeclaredConstructor 根据参数获取声明的开工构造方法。

特例:变长参数的构造方法获取

public class A{
  public A(String... names){}
}
public void useA() throws Exception{
  Constructor<A> constructor = A.class.getDeclaredContructor(String[].class);//变长参数底层就是数组实现
  constructor.newInstance((Object) new String[]{"A","B","C"});
}//<span style="font-family: Arial, Helvetica, sans-serif;">实际使用需要转换为Object类型,编译器就知道这个字符串数组作为变长参数传递</span>

三、获取域

获取公开的域

Field fCount = B.class.getDeclaredField("count");
fCount.set(null, 3);//静态域
Field fName = B.class.getDeclaredField("name");
B b = new B();
fName.set(b, "Bob");//实例域
Field出了提供操作Object 的set和get,还有一堆setBoolean/getBoolean,和其他所有基本类型的s/g.

四、获取方法

class的四个方法, 和构造方法一样,不解释。

getMethods

getMethod

getDeclaredMethods

getDeclaredMethod

A a = new A();
Method publicM = A.class.getDeclaredMethod("publicMethod");
publicM.invoke(a);

Method privateM = A.class.getDeclaredMethod("privateMethod");
privateM.setAccessible(true);//构造方法和域不具备,反射可以获得私有方法并修改访问权限。
privateMethod.invoke(a);

五、操作数组

与一般Java对象不同,数组通过 java.lang.reflect.Array来访问。

String[] names = (String[]) Array.newInstance(String.class, 10);
names[0] = "Hello";
Array.set(names, 1, "World");
String str = (String) Array.get(names, 0);
int [][][] matrix1 = (int[][][]) Array.newInstance(int.class, 3, 3, 3);
matrix1[0][0][0] = 1;
int [][][] matrix2 = (int[][][]) Array.newInstance(int[].class, 3, 4);
matrix[0][0] = new int[10];
matrix[0][0][0] = 1;

六、访问权限与异常

1、通过反射可以访问对象的私有方法

2、invoke方法调用方法,如果方法本身抛出异常,invoke方法会抛出InvocationTargetException异常

捕获后,通过InvocationTargetException异常的getCause方法获得真正的异常信息。

3、java7 给所有与反射操作相关的异常添加了一个新的父类java.lang.ReflectiveOperationException,可以直接捕获之,过去这些异常需要分别捕获。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值