运行和调试程序Java,Eclipse

时间:2016-01-15 17:16:54

标签: java eclipse debugging

我有这个代码(现在暂且不合适):<​​/ p>

    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 betterCache[] = new Integer[255];
    for (int i = 0; i < betterCache.length; i++) {
        betterCache[i] = 20;
    }
    cacheField.set(null,  betterCache);
    System.out.println(10);
    System.out.println((Integer) 10);

我希望第二个println打印20,因为我用20替换了缓存的Integers。当我在Eclipse中调试程序时它按预期执行,它从缓存中获取值并打印20 ,当我从IDE或通过调用java运行它时,它在两种情况下都打印10。如何解释这种行为?

UPD: 如果使用1.8 javac编译,它会以这种方式工作。如果使用1.6版本编译,则打印10和20。

2 个答案:

答案 0 :(得分:5)

这绝对是由Just in Time Compiler引起的。您应该将-XX:+ PrintCompilation添加到JVM选项,如果迭代

,它也会更加明显
System.out.println((Integer) 10);
很多次。 你会注意到编译

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

java.nio.ByteBuffer::arrayOffset (35 bytes) 

影响结果。

答案 1 :(得分:2)

修改

我完全错了

在我的观点中,绝对是在玩火,这是针对竞争条件(java 8中的不安全线程)。如果你检查一下:

    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);     
    }

你会看到Java刻录。