Java 基础整理(二)

163 阅读1分钟

这是我参与更文挑战的第 2 天,活动详情查看: 更文挑战

  1. 基础类型的缓存机制,设计模式

    Integer默认缓存是-128到127之间

    Boolean,缓存了true/false对于实例,确切的说,只会返回两个常量实例。Boolean.TRUE/FALSE

    Short,同样是缓存了-128到127之间的数值

    Byte,数值有限,所以全部都被缓存

    Character,缓存范围’\u0000’ 到 ‘\u007F’

    缓存上限值实际是可以根据需要调整的,JVM 提供了参数设置:-XX:AutoBoxCacheMax=N

    可以看看Integer内部类IntegerCache的缓存,代码如下

    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() {}
    }
    //缓存范围
    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
    }
    

    Java 的对象都是引用类型,如果是一个原始数据类型数组,它在内存里是一段连续的内存,而对象数组则不然,数据存储的是引用,对象往往是分散地存储在堆的不同位置。这种设计虽然带来了极大灵活性,但是也导致了数据操作的低效,尤其是无法充分利用现代 CPU 缓存机制。

  2. 深拷贝和浅拷贝的区别?

    对象A 复制出一个对象B 来。修改对象B 中的 8中基本类型(包括装箱)的值和String。对象A 中不更改。修

    改对象对象B中的 引用对象。对象A 中的引用对象也会更改。

    深拷贝。对象A复制出来一个对象B来。修改对象B 中的8种基本数据类型。和引用对象。对象A中的值不会修改。

    只包含 基本数据类型 和不可变类 不会影响独立性。

    浅拷贝对于可变引用属性 只会拷贝其引用,原对象和拷贝对象,不是相互独立的。

    深拷贝对于可变引用属性也会为这个属性再创建新对象,最终出来的拷贝对象是完全独立的。

  3. 泛型无法用基本数据类型,为什么?

    Java中的泛型是一个完全编译时的结构-编译器将所有泛型使用转换为正确的类型。这是为了保持与以前的JVM运行时的向后兼容性。

    这个:

    List<ClassA> list = new ArrayList<ClassA>();
    list.add(new ClassA());
    ClassA a = list.get(0);
    

    变成(大致):

    List list = new ArrayList();
    list.add(new ClassA());
    ClassA a = (ClassA)list.get(0);
    

    因此,任何用作泛型的东西都必须可转换为Object(在此示例中get(0)返回Object),而原始类型则不是。因此它们不能用于泛型。

  4. Switch—Case支持的类型

    byte,short,char,int,enum(Java 7),String(6种),不支持包装类,但是如下代码又是正确的

    switch (new Integer(33)){ //通过,因为自动装修和拆箱
                case 43:
                    break;
                case Integer.valueOf(88): //报错
                    break;
            }
    

w