==与equals、自动装箱、String类型相关

本文解析了Java中==和equals的区别,讲解了基本类型和引用类型的比较方式,并详细讨论了装箱拆箱现象,以及STRING类型在创建、拼接和StringBuilder的使用。特别关注了String对象的创建和内存优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

==和EQUALS的区别?

装箱与拆箱

自动装箱:

自动拆箱:

STRING类型相关

创建字符串

拼接String字符串

StringBuilder如何添加新字符


==和EQUALS的区别?

equals:比较两个引用类型的地址(有重写的特殊情况

== :比较两个基本数据类型的值,比较两个引用类型的地址

1、基本数据类型

== 比较的是值

2、普通引用类型

没有重写equals方法,自动继承的Object类的方法,比较地址。

== 和 equals比较的都是地址

3、特殊的引用类型

Srting类、Integer类、Date类,java重写equals()方法,比较的是值。

装箱与拆箱

自动装箱:

装箱:把基本数据类型转换为对应的包装类类型

基本类型的数据处于需要对象的环境中时,会自动转为“对象”,由自动装箱过程通过调用包装类的valueOf()方法实现的。

 Integer i = 5; //代码
 Integer i = Integer.valueOf(5);//编译器转换,自动装箱

只需Integer i = 5这样的语句就能实现基本数据类型转换成包装类,这是因为JVM为我们执行了Integer i = Integer.valueOf(5)这样的操作,这就是Java的自动装箱。

注意:对于Integer类的特殊情况

Integer.valueOf(int/String num);源代码如下

“valueOf()会返回一个Integer(整型)对象,当被处理的字符串或数字在-128和127(包含边界)之间时,返回的对象是预先缓存的。”,因此用该方法获得[-128,127]的对象,相同的数值获得是相同的对象。

 public static Integer valueOf(int i) {
         if (i >= IntegerCache.low && i <= IntegerCache.high)
             return IntegerCache.cache[i + (-IntegerCache.low)];
         return new Integer(i);
 }
 ​
 public static Integer valueOf(String s) throws NumberFormatException {
         return Integer.valueOf(parseInt(s, 10));
 }

自动拆箱:

拆箱:把包装类类型转换为对应的基本数据类型。

每当需要一个值时,对象会自动转成基本数据类型,由自动拆箱过程通过调用包装类的如intValue()、doubleValue()等方法实现的。

 Integer i = 5;
 int j = i; //代码
 int j = i.intValue()//编译器转换,自动拆箱

注意:可能导致空指针异常的情况

 public class Test1 {
     public static void main(String[] args) {
         Integer i = null; 
         int j=i;
         //在编译时期是合法的,但是在运行时期会有错误,因为其相当于:
         int j = i.intValue();         
     }
 }

null表示i没有指向对象实例,因此编译后使用空引用调用了方法,导致产生了空指针异常。

STRING类型相关

创建字符串

使用new关键字新建一个字符串对象时,JVM首先在字符串常量池中查找有没有"xyz"这个字符串对象

如果字符串常量池中有,则直接在中创建一个"xyz"字符串对象,然后将中的这个"xyz"对象的地址返回;

如果字符串常量池中没有,则首先在字符串常量池创建一个"xyz"字符串对象,然后再在创建一个"xyz"字符串对象,然后将中这个"xyz"字符串对象的地址返回。

 String s1 = new String("xyz");//创建两个对象,字符串常量池中一个"xyz",堆上一个"xyz"
 String s2 = new String("xyz");//堆上创建一个"xyz"
 System.out.println(s1==s2);

因此上述代码一共创建了三个字符串对象,new第一个String对象时,字符串常量池中没有"xyz",所以在字符串常量池中创建一个"xyz",堆上在创建一个"xyz",new第二个String对象时,只在堆上创建一个"xyz"。

拼接String字符串

+如何拼接String字符串?

字符串常量在拼接过程中,会先创建一个StringBuilder对象,然后再使用append()方法将需要连接的字符串添加到该对象中,最后使用StringBuilder对象的toString()方法获得一个String字符串。

concat如何拼接字符串?

首先分别获得原字符串和拼接字符串的长度,按照该长度用Arrays.copyOf()获得一个新字符数组,且将原字符串复制到字符数组中,然后用getChars()将拼接字符串复制到字符数组中,再新建一个String字符串返回。

 
    public String concat(String str) {
         int otherLen = str.length();//获得拼接部分的长度
         if (otherLen == 0) {
             return this;
         }
         int len = value.length;//获得原字符串长度
         //获得一个新的字符数组,长度为原字符串长度与拼接字符串长度之和
         char buf[] = Arrays.copyOf(value, len + otherLen);
         str.getChars(buf, len);//将字符串内容复制到字符数组后面
         return new String(buf, true);//新建一个String字符串并返回
     }

创建了几个对象?

 String str = "abc" + new String("def");
 //等同于
 String s = new String("def");
 new StringBuilder().append("abc").append(s).toString();

对比等价代码,执行【new String("def");】会在字符串常量池分别创建一个"def"对象,然后在字符串常量池创建一个"abc"对象,由于使用了【+】,先在堆上创建一个StringBuilder对象,然后使用该对象的append()方法将"abc"字符串添加到StringBuilder对象中,最后使用toString()方法获得一个String对象。

因此,字符串常量池中创建了"def"对象"abc"对象、堆中有StringBuilder对象"abcdef"对象"def"对象,一共5个对象字符串

StringBuilder如何添加新字符

  • value[] : 用来存储StringBuilder对象中的字符,以下称内容数组,其长度可在创建对象时通过构造函数初始化,若未初始化则默认初始长度为16

  • count: 记录StringBuilder对象中所存字符的实际数量,以下称实际内容长度

sb.append(str)的添加流程:

判断count + str.length > char.length?

(1)内容数组容量足够,直接将str复制存入内容数组。

(2)内容数组容量不足够则扩容,即扩大长度为原长度 * 2再加2,即char.length * 2 + 2,此时再次比较是否足够,char.length * 2 + 2 < count + str.length?

i: No 即足够,此时容量足够,将str复制存入内容数组, 此时内容数组长度为char.length*2 + 2。更新实际内容长度 count += len

ii:yes 不足够,则内容数组长度增加至 count + str.length, 并将str复制存入内容数组,此时实际内容长度为:count += len

Array.copyOf(int[] a,int len) 用于复制指定的数组内容以达到扩容的目的。创建一个新的长度为len数组的数组并返回,且将旧数组a的内容复制给新数组。若len长度小于a数组长度,则新数组长度为a数组长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值