Java 反射有效的修改 final 属性值

两年前写过一篇 Java 反射修改 final 属性值, 在这里重新温习一下,假设有个类

class Person {
    public final String name = "Mike";
}

这里声明 name 为非静态的属性只是为了说明反射修改 final 属性无关乎静态不静态,静态只是表现在它是一个类属性,在一个类加载器空间只会有一份拷贝,仅此而已。

创建一个通用方法进行反射修改属性值

调用 modify(...) 方法试图修改 person 的 name 属性 阅读全文 >>

类别: Java/JEE. 标签: . 阅读(49). 评论(0) »

Java 下高效的反射工具包 ReflectASM 使用例解

ReflectASM 使用字节码生成的方式实现了更为高效的反射机制。执行时会生成一个存取类来 set/get 字段,访问方法或创建实例。一看到 ASM 就能领悟到 ReflectASM 会用字节码生成的方式,而不是依赖于 Java 本身的反射机制来实现的,所以它更快,并且避免了访问原始类型因自动装箱而产生的问题。

下面三个图是 ReflectASM 与 Java 自身反射机制的性能对比,表现很不错的。

测试代码包含在项目文件中. 上面图形是在  Oracle 的 Java 7u3, server VM 下测试出的结果。

下面我们自己来做个测试,测试环境是 Mac OS X 10.8, 2.4G Core 2 Duo, 4G RAM, 64 位 JDK 1.6. 阅读全文 >>

类别: Java/JEE. 标签: , , . 阅读(8,185). 评论(0) »

使用Java的反射调用方法应注意的异常处理

先看下面的代码,看看程序执行会是什么样的结果:

简单分析上面的代码,代码中自定义了一个异常类,main调用了方法foo1,而方法foo1调用了方法foo2,在方法foo2中抛出的异常是MyException,该异常向上传播,在main方法中被catch,那么是不会会第一个catch语句捕获到,在控制台下打印出"Exception Type: MyException"呢?其实不然,异常会被第二个catch语句捕获,实际执行结果是"Exception Type: Exception"。

也就是尽管foo2方法中抛出的是MyException,但是让foo1通过反射方式调用后,异常被重新封装。从foo1方法中执向外面的异常实际是"InvocationTargetException",也就是执行method.invoke方法的异常了,那么在foo1中如何知道触发的实际异常呢,InvocationTargetException有一个方法getTargetException()可以获取到是MyException异常。

如果我们想在main方法中更细致的处理实际方法执行所抛出的异常,应如何做呢?我们可以改写foo1中的反射调用代码行

替换如下,让在foo2中触发的实际异常向外抛

这样的话,这个异常将在main方法的第一个catch块被捕获,异常类型被还原成MyException。

我是在项目中使用Struts,写了一个BaseAction,在BaseAction中根据参数反向调用相应的Action Perform方法时,在BaseAction中也是写成上面代码那样的异常捕获方式,结果发现只要是Action Perform方法中抛出的异常总是作为Exception被捕获的,而不能正确处理异常中描述的业务含业。

用Struts做项目时,经常会写自己的BaseAction,由这个BaseAction去分发执行哪一个实际方法,并且由它统一根据上抛的异常处理错误信息时就应该注意到这种问题。

类别: Java/JEE. 标签: , , . 阅读(607). 评论(0) »