Java里的包装类型

2023-10-28

Java里的包装类型

其实也就那么几个

基础数据类型&包装类型

​ 和面向过程的编程不同,Java里,一切皆对象,但是就有那么一些例外,就是常见的int,char,boolean,float,double,byte,short,long,八大基础数据类型,基础类型,没他不行,但是和其他对象的操作又不一样,于是Java对基础数据类型进行了上层封装,也就是所谓的包装类型

基础数据类型 包装类型
int Integer
char Character
boolean Boolean
short Short
long Long
byte Byte
float Float
double Double

​ 包装类型中,除了intchar,其余的包装类型仅仅是基础类型首字母大写,包装类型提供了面向对象的性质,可以计算HashCode,使用equals进行对比等,既然是把它当作对象,肯定和基础数据类型有区别

public class WrapprTest {
    public static void main(String[] args) {
        int num = 1;
        Integer a = new Integer(num);
        Integer b = new Integer(num);
        System.out.println("a == b:"+(a == b));
        System.out.println("a != b:"+(a != b));
        System.out.println("a > b:"+(a > b));
        System.out.println("a < b:"+(a < b));
        System.out.println("a >= b:"+(a >= b));
        System.out.println("a <= b:"+(a <= b));
    }
}

​ 结果如下:

a == b:false
a != b:true
a > b:false
a < b:false
a >= b:true
a <= b:true

Process finished with exit code 0

​ 结果表明,当使用==!=的时候,直接比较的是对象的地址,两个对象地址不同所以返回的是false,当使用>,<,>=,<=的时候,会直接比较两个对象对应的值,至于equals函数

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
}

​ 直接比较的是int的值,所以返回true

装箱与拆箱

// 装箱,将基础数据类型封装成包装类型
Integer i = new Integer(1);
// 拆箱,将包装类型包装的基础类型取出
int num = i.intValue();

​ JDK1.5之后就有了自动装箱和拆箱

Integer i = 1;
int num = i;

自动装箱过程中的内存复用

​ 看一段代码

public class WrapprTest {
    public static void main(String[] args) {
        int num1 = 100;
        int num2 = 200;
        Integer a = num1;
        Integer b = num1;
        System.out.println(a == b);
        a = num2;
        b = num2;
        System.out.println(a == b);
    }
}

==直接比较的是对象在内存中的地址,结果是true和false

​ 要解释这个问题,首先要知道,自动装箱是基于valueOf()函数实现的,瞅一瞅它的实现

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}

​ 我们发现了一层缓存,当给定的i值在缓存的区间里的时候,会直接从缓存中拿到这个对象,否则就去新建一个对象,缓存中都是一些常用的对象,接下来看一下lowhigh分别是多少

		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() {}
    }

​ 这里看来,low永远是-128,但是high的值可以自己设置,最小是128,最大是Integer.MAX_VALUE - (-low) -1

# 设置整数的缓存复用范围
java -D java.lang.Integer.IntegerCache.high=200 CLASSNAMEE
# 设置自动装箱的缓存复用
java -XX:XX:AutoBoxCacheMax=200 CLASSNAME
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java里的包装类型 的相关文章

随机推荐