zoukankan      html  css  js  c++  java
  • Java小陷阱

      基本数据类型与字符串的连接

      

      在Java中,+不仅可作为加法运算符使用,还可作为字符串连接运算符使用。

      当把任何基本数据类型的值与字符串值进行连接运算时,基本类型的值将自动类型转换为字符串类型。

      

    public class PrimitiveAndString
    {
        public static void main(String[] args)
        {
            //下面的语句输出 7Hello!
            System.out.println(3 + 4 + "Hello!");
    
            //下面的语句输出 Hello!34
            System.out.println("Hello!" + 3 + 4);
    
            //下面的语句输出 Hello!a7
            System.out.println("Hello!" + 'a' + 7);
    
            //下面的语句输出 104Hello!
            System.out.println('a' + 7 + "Hello!");
        }
    }

      上面程序中第一个”3 + 4 + "Hello!"“的表达式,这个表达式先执行”3 + 4“运算,这是执行两个整数之间的加法,得到7,然后进行”7 + "Hello!"“的运算,此时会把7当成字符串进行处理,从而得到7Hello!。

      第二个,对于”"Hello!" + 3 + 4“表达式,先进行”"Hello!" + 3“运算,得到一个Hello!3字符串,再和4进行连接运算,4也被转换成字符串进行处理,最后得到Hello!34。

      第三个表达式”"Hello!" + 'a' + 7“同第二个类似。

      对于最后一个表达式”'a' + 7 + "Hello!"“,先进行”'a' + 7“加法运算,其中'a'自动提升到int类型,编程a对应的ASCⅡ值:97,从”97+7“将得到104,然后进行”104 + "Hello!"“运算,104会自动转换成字符串,将变成两个字符串的连接运算,从而得到104Hello!。

      Integer自动装箱的缓存机制

      (2016年腾讯实习生招聘笔试题,扩展)下面这段java代码的输出结果是?(不考虑java 1.5之前的老版本,因为老版本不支持自动装箱)

    public class IntegerTest {
    
        public static void main(String[] args) {
            
            Integer i1 = 127;   // autoboxing
            Integer i2 = 127;   // autoboxing
            System.out.println(i1.equals(i2));   // true
            System.out.println(i1 == i2);        // true
    
            Integer i3 = 128;   // autoboxing
            Integer i4 = 128;   // autoboxing
            System.out.println(i3.equals(i4));   // true
            System.out.println(i3 == i4);        // false
    
            Integer i5 = new Integer(127);
            Integer i6 = new Integer(127);
            System.out.println(i5.equals(i6));  // true
            System.out.println(i5 == i6);       // false
    
            Integer i7 = 127;   // autoboxing
            Integer i8 = new Integer(127);
            System.out.println(i7.equals(i8));  // true
            System.out.println(i7 == i8);       // false
    
            int i = 127;
            System.out.println(i7.equals(i));   // true
            System.out.println(i8.equals(i));   // true
            System.out.println(i7 == i);        // true
            System.out.println(i8 == i);        // true
        }
    }

      分析:本题的考察点在于Integer类对于[-128 , 127]之间的整数自动装箱缓存的机制,查看Java系统中java.lang.Integer类的源代码,其中有一个叫做IntegerCache的静态内部类如下:

        /**
         * Cache to support the object identity semantics of autoboxing for values between
         * -128 and 127 (inclusive) as required by JLS.
         *
         * The cache is initialized on first usage.  The size of the cache
         * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
         * During VM initialization, java.lang.Integer.IntegerCache.high property
         * may be set and saved in the private system properties in the
         * sun.misc.VM class.
         */
    
        private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            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) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }

       从上面的代码可以看出,系统已经把[-128 , 127]之间的256个整数自动装箱成Integer实例,并放入了cache数组中缓存起来

      当把[-128 , 127]之间的同一个整数自动装箱成Integer实例时,永远都是引用cache数组的同一个元素,(i1 == i2)结果为true;

      当把一个不在[-128 , 127]范围内的整数自动装箱成Integer实例时,系统总是重新new一个Integer实例,开辟新的内存空间,因此(i3 == i4)、(i5 == i6)、以及(i7 == i8)的结果均为false;

      Integer和int进行比较时,Integer会自动拆箱成int类型变成值比较,因此(i7 == i)和(i8 == i)的结果均为true;

      Integer类重写了从Object类继承而来的equals方法进行值比较,所以上述equals的结果均为true

  • 相关阅读:
    【Android】GLSurfaceView
    【Android】手机分辨率
    【Mac】快捷键锁屏
    【Android】View
    【Android】状态保存
    【Android】Notification
    【Android】ContentProvider
    【Android】Bitmap的管理
    【Android】缩略图Thumbnails
    【Android】Activity生命周期
  • 原文地址:https://www.cnblogs.com/eniac12/p/4890444.html
Copyright © 2011-2022 走看看