==和equals()详解

误区不知道从哪里听来的==比较的是地址和值,equals比较的是值。这是大错特错的。

==

首先 ==在比较基本数据类型的时候比较的是值,而比较对象的时候比较的是两个对象的地址。

  • 数组属于对象,所以在比较数组的时候是以比较对象得方式
int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(x == y); // 输出true
System.out.println(str1 == str2); // 输出false

equals

  • equals()方法存在于Object类中
  • equals()方法可以被重写
  • 大多数Java的数据封装都重写了equals()方法
  • 查看源码可以得知equals()底层的实现依赖的其实是==

==和equals()

首先==和equals()最大的区别就是一个是运算符一个是方法,在Java中二者比较的都是物理地址,而不是值的比较。

Student student1 = new Student();

Student student2 = new Student();

System.out.println(student1.equals(student2));//false

System.out.println(student1 == student2);//false

不论是用的是哪一种方法 , 最终的结果显示的都是false,大家不妨可以试一下。为什么呢?就是因为他们比较的不是对象中字段的值或者说本身对象的值,而比较的是物理地址。

所以在没有重写equals()方法的类中,使用equals和使用==其实是一样的,但是在多数Java的类中,大多都重写了equals()方法,并且大多数一般都是指定它去比较两个对象的值。
在这里插入图片描述
这里我们自定义的Student类并没有重写String方法,所以输出结果是false。

在这里插入图片描述
在重写了equals()方法以后,指定让它比较值的大小,所以输出为true。

特殊的关键字String

String简介

JDK1.8中JVM把String常量池移入了堆中,同时取消了“永久代”,改用元空间代替(Metaspace)
java中对String对象特殊对待,所以在heap区域分成了两块,一块是字符串常量池(String constant pool),用于存储java字符串常量对象,另一块用于存储普通对象及字符串对象。

下面是String的创建方式:

public static void main(String[] args) {
    String a = "abc";  //第一种
    String b=new String("abc"); //第二种
    String c = "abc";
    System.out.println(a == b);//false
    System.out.println(a == c);//true
}
  • 对于第一种,此创建方法会在Java constant pool中创建对象。JVM首先会在常量池中寻找是否存在"abc"常量,如果没有则创建该常量,并且将此常量的引用返回给String a;如果已有"abc" 常量,则直接返回String constant pool 中“abc” 的引用给String a。
  • 对于第二种,jvm会直接在非String constant pool 中创建字符串对象,然后把该对象引用返回给String b,并且不会把"abc” 加入到String constant pool中。new就是在堆中创建一个新的String对象,不管"abc"在内存中是否存在,都会在堆中开辟新空间。
  • 虽然new String()方法并不会把"abc” 加入到String constant pool中,但是可以手动调用String.intern(),将new 出来的字符串对象加入到String constant pool中。
String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1 == s2); //false
System.out.println(s1.intern() == s2); //true

String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);

所以在这个方法中,两个方法都是true,因为当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值