Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
运行和调试Java、Eclipse程序的不同行为_Java_Eclipse_Debugging - Fatal编程技术网

运行和调试Java、Eclipse程序的不同行为

运行和调试Java、Eclipse程序的不同行为,java,eclipse,debugging,Java,Eclipse,Debugging,我有以下代码(暂时不考虑其适当性): Class cacheClass=Class.forName(“java.lang.Integer$IntegerCache”); 字段cacheField=cacheClass.getDeclaredField(“缓存”); cacheField.setAccessible(true); 字段修饰符字段=Field.class.getDeclaredField(“修饰符”); modifiersField.setAccessible(true); setI

我有以下代码(暂时不考虑其适当性):

Class cacheClass=Class.forName(“java.lang.Integer$IntegerCache”);
字段cacheField=cacheClass.getDeclaredField(“缓存”);
cacheField.setAccessible(true);
字段修饰符字段=Field.class.getDeclaredField(“修饰符”);
modifiersField.setAccessible(true);
setInt(cacheField,cacheField.getModifiers()&~Modifier.FINAL);
整数betterCache[]=新整数[255];
for(int i=0;i
我希望第二个
println
打印20,因为我用20替换了缓存的
整数。当我在Eclipse中调试程序时,它会按照我的预期执行,它从缓存中获取值并打印20,而在这两种情况下,当我从IDE或通过调用
java
运行它时,它都会打印10。如何解释这种行为

UPD: 如果用1.8javac编译,它就是这样工作的。如果使用1.6版本编译,它将打印10和20。

编辑

我完全错了

在我看来,您肯定是在玩火,这是针对竞争条件(Java8中的不安全线程)。如果您选中此项:

    Class<?> cacheClass = Class.forName("java.lang.Integer$IntegerCache");
    Field cacheField = cacheClass.getDeclaredField("cache");
    cacheField.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(cacheField, cacheField.getModifiers() & ~Modifier.FINAL);
    Integer firstCache[] = (Integer[])cacheField.get(null);
    Integer betterCache[] = new Integer[255];
    for (int i = 0; i < betterCache.length; i++) {
        betterCache[i] = 20;
    }
    System.out.println(firstCache == betterCache);
    cacheField.set(null, betterCache);
    System.out.println(10);
    for (int i = 0; i < 1000000; i++) {
        System.out.println((Integer) 10);     
    }
Class cacheClass=Class.forName(“java.lang.Integer$IntegerCache”);
字段cacheField=cacheClass.getDeclaredField(“缓存”);
cacheField.setAccessible(true);
字段修饰符字段=Field.class.getDeclaredField(“修饰符”);
modifiersField.setAccessible(true);
setInt(cacheField,cacheField.getModifiers()&~Modifier.FINAL);
Integer firstCache[]=(Integer[])cacheField.get(null);
整数betterCache[]=新整数[255];
for(int i=0;i

您将看到Java烧录。

这肯定是由即时编译器造成的。您应该将-XX:+printcomilation添加到JVM选项中,如果您进行迭代,它也会更加可见

System.out.println((Integer) 10);
很多次。 你会注意到

java.lang.Integer::valueOf (32 bytes)


影响结果。

两种情况下都打印10。那么它为什么要打印20呢?在第二种情况下,它是一个对象,所以它调用
Integer.valueOf
方法来打印它,在该方法中,它从缓存中获取值,我刚才用一个填充了20的数组来替换。有趣的问题(尽管你正在玩火)。你试过maven或java-jar吗?我认为一些IDE的缓存可能会导致这个问题。你可能会在有趣的网站上找到答案,因为你正在处理像那个问题一样的最终问题。谢谢你的回答。我仍然不明白为什么将
20
(基本上调用
valueOf
)更改为创建新的值会改变这种行为。它似乎不是在编译时计算的(虽然字节码的内容对我来说非常不清楚),因为在两个版本的字节码中,第二个版本的
println
有相同的语句
bipush 10
。请参阅我的question@cliffroot我不知道,但我可以看到在调试模式下使用断点与不使用断点的区别。我开始考虑竞争条件。Art Taylor:“我有两条新规则。1)如果你的应用程序运行缓慢,请添加缓存。2)如果你的应用程序有缺陷,请删除缓存。”哈哈,你知道有什么好笑的。我试了100圈。有时它写下20作为第一个值,然后全部写下10,有时它不(全部10)@cliffroot当我尝试1000000时,它显示158,WTF!你介意解释一下
-xx:+printcomployment
的输出吗。。。我经历过,但真的不太明白。。。
java.lang.Integer::valueOf (32 bytes)
java.nio.ByteBuffer::arrayOffset (35 bytes)