自动装箱和拆箱

装箱:将基本数据类型变成包装类
拆箱:将包装类变成基本数据类型

那么如何实现装箱和拆箱呢,从Java SE5开始就提供了自动装箱的特性,所以输入以下程序即可,如

Integer i = 15//装箱

有了装箱那么怎么拆箱呢,如下

Integer i = 15//装箱
int n = i;//拆箱

下表是基本数据类型对应的包装器类型

基本数据类型包装类型
byte(1个字节)Byte
char(2个字节)Character
short(2个字节)Short
int(4个字节)Integer
long(8个字节)Long
float(4个字节)Float
double(8个字节)Double
boolean(未指定)Boolean

自动装箱和拆箱是如何实现的呢?我们先输入以下代码

public class wy1 {
    public static void main(String[]args){
       Integer i = 15;//装箱
       int n = i;//拆箱     
}
}

编译运行后反编译class文件,得到以下反编译
这里写图片描述

我们从中可以看到装箱时所用的是valueOf的方法
拆箱所用的是intvalue的方法
那么valueOf方法是怎样的呢?

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

low表示最小值为-128,high表示最大值为127
Cache为缓存
意思是在-128~127内的数据会存储在缓存中,当数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;

public class Wy1 {
    public static void main(String[] args) {

        Integer a = 125;
        Integer b = 125;

        System.out.println(a == b);
    }
}

此时所输出的为true,是因为125在[-128,127]之间,是cache中已经存在的对象肯定是相同的,所指的是同一对象
但是一旦超出范围,如

public class Wy1 {
    public static void main(String[] args) {
        Integer c = 130;
        Integer d = 130;

        System.out.println(c == d);
    }
}

此时所输出的结果为false;这是为什么呢?我们需要了解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) {
                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);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

从代码中可以看出,如果数值是在[-128~127]之间,那么会在缓存中返回指向已存储的对象,否则需要新建一个Integer对象
c和d的值为130,所以指的是不同的对象
那么我们看以下代码

public class Wy1 {
    public static void main(String[] args) {
        Double e = 100.0;
        Double f = 100.0;

        System.out.println(e == f);
    }
}

此时输出的结果为false,这是因为此时采用了DoublevalueOf的方法

public static Double valueOf(String s) throws NumberFormatException {
        return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue());
    }

valueOf方法在返回的生活new Double(),所以返回的是新建的一个Double对象,会显示false。
我们再看如下代码:

public class Wy1 {
    public static void main(String[] args) {

        Boolean g = false;
        Boolean h = false;
        Boolean i = true;
        Boolean j = true;

        System.out.println(g == h);
        System.out.println(i == j);
    }
}

此时的输出结果为true true,这又是为什么呢?我们来查看一下Boolean.valueOf的源码

 public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

对象相等比较
“==”可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,这个比较过程中没有自动装箱发生。进行对象值比较不应该使用”==”,而应该使用对象对应的equals方法。
对于”==”,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址是否相同。
对于equals,其对于String源码如下

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

其中instanceof是比较类型的意思,我们来看道题
假设有以下代码

String s = "hello";
String t = "hello";
char c[] = {'h', 'e', 'l', 'l', 'o'};

s.equals(t);
t.equals(c);
s==t;
t.equals(new String (“hello”));

t.equals(c);应为false
在采用equals方法时,我们要分以下步骤来分析结果:
1.先比较是否都是引用类型,引用相等直接true
否则的话:
①.比较类型
②.比较长度
③.把string转成char[], 依次比较每一个字符,全部相等则为true,否则为false。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值