java8u162反射机制的一个BUG


import java.io.File;
import pers.laserpen.util.java.BinaryClassLoader;
import pers.laserpen.util.java.Reflection;
import pers.laserpen.util.java.StaticJavaTools;

public class Test {

public static void main(String[] args) {
for (int i = 1; i < 3; ++i) {
            //使用二进制方式读取类文件
BinaryClassLoader bcl = new BinaryClassLoader(new File("."));
bcl.searchClass("Test$R");
System.out.println(bcl.getLoadedClass());//这里显示一次读取到的文件

Reflection ref = new Reflection(true, bcl.getLoadedClass());//利用反射创建一个对象
System.out.println(bcl.getLoadedClass(http://www.amjmh.com/v/));//这里本应该显示和之前一样的类名,但是却变成了PrintStream。
int t = ref.staticValue(true, "i");
System.out.println("reflection get:" + t);
ref.staticValue(true, "i", i);
System.out.println("reflection get after set:" + ref.staticValue(true, "i"));
System.out.println("directly get:" + R.i);
System.out.println(StaticJavaTools.isAssignableClass(ref.getObjectClass(), R.class));

}
}

public static class R {
static int i = 0;
static {
                        //在这个静态代码段中最后一次用到的类会被写入BinaryClassLoader中。
i = Integer.parseInt("0");
System.out.println("R loaded");//单步调试时,这一步以后才改变了BinaryClassLoader的私有成员变量。这一步用到的类型是什么,那个成员变量就会被改成什么。与具体的操作无关。
}

}

}
这个BUG并不重要,正常的程序不会遇到这种情况。可能是java反射机制和我的代码发生了耦合,导致一个私有成员变量的引用被更改了。单步调试发现是一个无关的步骤改变了那个成员变量,所以可以认定是java中的BUG。这个工具类是我自己编写的,读者如果编写自己的工具类,估计也可能会有各种奇怪的现象。

另外,还有一个不是BUG的现象也顺便说一下。不同类加载器对象加载的类使用的静态变量是不同的。对类型进行equals比较也只能返回false。但是对父类进行instanceof判定可以返回true。
---------------------

posted @ 2019-08-10 14:44  水至清明  阅读(292)  评论(0编辑  收藏  举报