前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA自动拆装箱、equals与==比较

JAVA自动拆装箱、equals与==比较

作者头像
chenchenchen
发布2023-01-30 17:03:41
3840
发布2023-01-30 17:03:41
举报
文章被收录于专栏:chenchenchen

一.自动拆装箱

自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。

java中有8中基本的数据类型,这八种基本的数据类型都有对应的封装类型,下面是对应关系:

int——Integer float——Float double——Double byte——Byte long——Long char——Character boolean——Boolean short——Short

1.引入原因

举个例子:主要是用于java集合中,List<Inteter> list=new ArrayList<Integer>(); list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象,基本数据类型,如int,float,double,boolean,char,byte,不具备对象的特征,不能调用方法。

2.又是怎么实现的呢?(怎么做)

实现原理:javac编译器的语法.

自动装箱过程是通过调用valueOf方法实现(如Integer.valueOf(10)),而拆箱过程是通过调用包装器的 xxxValue方法实现(如Integer.intValue(a))。

(举个例子)

装箱:将基本类型转换成包装类对象

int i=10; Integer x=new Integer(i);手动装箱 Integer y=10;自动装箱 拆箱:将包装类对象转换成基本类型的值 Integer j=new Integer(8); int m=j.intValue();//手动拆箱 int n=j;//自动拆箱

看下面这段代码,为什么?(T为true,F为false)

public class Main {     public static void main(String[] args) {          int i = 30;         Integer a = 10;         Integer b = 20;         Integer c = 30;         Integer d = 30;         Integer e = 320;         Integer f = 320;         Long g = 30L;         Long h = 20L;         System.out.println(i==(a+b));//T         System.out.println(c==d);//T         System.out.println(e==f);//F         System.out.println(c==(a+b));//T         System.out.println(c.equals(a+b));//T         System.out.println(g==(a+b));//T         System.out.println(g.equals(c));//F         System.out.println(g.equals(a+b));//F         System.out.println(g.equals(a+h));//T,a和h自动拆箱后进行add运算的会向上转型为long类型     } }

3解释:

1) "=="运算符既可以用来比较基本类型变量和引用类型变量。当两个操作数都是包装器类型的变量时,判定标准为他们是否指向同一个对象;而如果其中有一个操作数是表达式(即包含算术运算)则会先进行自动拆箱,再进行对应基本类型变量比较。

2)基本包装类型重写了equals方法,基本包装类型的equals不会进行类型的转换,类型不同的包装类型的变量直接被判定为false,尽管他们的数值有可能是相等的。

Integer的equals源码如下:

代码语言:javascript
复制
    public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
    }

如果obj如果符合instanceof判定,那么会将obj自动拆箱,实际比较的是两个Integer对象的数值。

这就解释了虽然e和f是不同的对象(==判定为false),但是equals判定为true,因为其数值都为250。

3)针对-128~+127之间的数据,做了一个数据缓冲池 ,就直接调用IntegerCache类,返回缓存中的数据,,则不创建新的对象,否则创建

自动装箱调用valueOf方法. 

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

4).注意点:

Integer、Short、Byte、Character、Long包装类型有缓存机制(cache数组)。

Boolean类型有TRUE 和 FALSE两个静态成员。Double和Float没有缓存机制。

(Double包装类的valueOf方法直接新建一个新对象)

(Boolean包装类valueOf方法,返回 (b ? TRUE : FALSE),)其他的请自行查看,判断.同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值,其实就是自动装箱的相反操作.

容易生成无用对象,因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作.

关于java的自动拆装箱若干细节问题https://www.cnblogs.com/qcblog/p/7670159.html

二、equals和==的比较

== 中基本数据类型比较的是值,复合数据类型比较对象的地址。

Object类中的equals方法和“==”是一样的,没有区别,而String,Double,Integer,Date,Point类等等一些类,是重写了equals方法,比较的是两个对象的内容是否相等

声明赋值语句是java中唯一不需要new 就可以产生对象的途径,即当声明一个变量后,JVM会在常量池中先查找有有没有一个值相同的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个,即以声明赋值的变量,只要值相等,任何多个引用都指向同一对象

”==”比”equal”运行速度快,因为”==”只是比较引用.

代码语言:javascript
复制
String s1 = "Monday";
String s2 = new String("Monday");

s1 == s2//false
s1 equals s2//true

-----------------------------------

String s1 = "Monday";
s2 = s2.intern();//检查字符串池里是否存在

s1 == s2//true
s1 equals s2//true
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、equals和==的比较
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档