zoukankan      html  css  js  c++  java
  • Java

    原出处是国外某论坛某帖子中楼主提问:如何让1+1=3?
    于是出现了各种语言实现的各种机制的答案,当然其中也包括直接用字符串输出"1+1=3"...
    最后被采纳的是用Java语言实现的答案。

    以下是答案:

    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
            Class cache = Integer.class.getDeclaredClasses()[0];
            Field c = cache.getDeclaredField("cache");
            c.setAccessible(true);
            Integer[] array = (Integer[]) c.get(cache);
            array[130] = array[131];
            System.out.printf("%d", 1 + 1);
    }

      

    作者解释:
    You need to change it even deeper than you can typically access.
    Note that this is designed for Java 6 with no funky parameters passed in on the JVM that would otherwise change the IntegerCache.
    Deep within the Integer class is a Flyweight of Integers. 
    This is an array of Integers from 128 to +127. cache[132] is the spot where 4 would normally be. Set it to 5.

    这样思路已经很明确了。
    Integer.class.getDeclaredClasses()[0]指向IntegerCache类,其cache域在静态初始化块内进行初始化,缓存-128到127,由此可知cache[130]==2。

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low));
        }
        high = h;
    
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    于是写出了如下代码,只可惜运行结果仍然是2:

    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
            Class cache = Integer.class.getDeclaredClasses()[0];
            Field c = cache.getDeclaredField("cache");
            c.setAccessible(true);
            Integer[] array = (Integer[]) c.get(cache);
            array[130] = array[131];
            System.out.println(1+1);
    }

    问题就出在printf还是println。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    参考println的方法声明,作者对于不同的基本类型都提供了overwrite,而printf并没有为基本类型提供方法。
    wKiom1P1x5uiJ_7FAADt9PjOSaM217.jpg
    wKiom1P1yGeRfS2nAAD6dtUCDzM911.jpg


    虽说printf("%d",1+1)相当于System.out.println(String.format("%d", 1 + 1));
    但问题的本质还是在于println(1+1)的结果仍是基本类型,并没有进行装箱。
    即,System.out.println((Integer)1+1);的结果为3.

     

  • 相关阅读:
    二维码生成库phpqrcode使用小结
    微信扫码支付开发小结
    Xcode下开发c静态库for ios CPU架构 静态库合并
    Android.mk的用法和基础
    Android.mk介绍
    查看与修改网关,DNS
    WebRTC编译系统之GYP,gn和ninja
    sed awk文本处理教程
    有哪些自媒体平台?
    camke使用例程
  • 原文地址:https://www.cnblogs.com/kavlez/p/java.html
Copyright © 2011-2022 走看看