java中equals与==经常容易混淆,简单一点说就是equals比较的是值是否相等,是一种方法,==比较的两个对象在JVM中的地址,是一种操作符。

做了几个小实验比较结果。

实验一:

String str1="ab";
String str2="ab";
System.out.println(s1==s2);//true
System.out.println(str1.equals(str2));//true

这里的str1与str2都指向了常量池中的同一对象,所以System.out.println(s1==s2);返回为true,当然,str1与str2二者字符串的值也是相同的。

实验二:

 String str1="ab";
String str2="abc";
System.out.println(str1==str2);//false
System.out.println(str1.equals(str2));//false

这里的str1指向了字符串ab,初始时在常量池中并没有找到字符串abc,则开辟地址存储字符串abc,并将str2指向了abc字符串,所以str1与str2与并不是一个对象,他们的字符串值也不相同。

实验三:

 String str1="ab";
String str2="ab";
String str6=str2;
System.out.println(str1==str6);//true
System.out.println(str2==str6);//true
System.out.println(str1.equals(str6));//true
System.out.println(str2.equals(str6));//true

这里将str2的值赋值给str6,因为常量池中已经存在了ab这个字符串,所以str1、str2与str6共享了同样的对象,==与equals同样返回true

实验四:

 String str1= new String("abc");
String str2= "abc";
System.out.println(str1==str2);//false

创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。
以上代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。

实验五:

 String str1="ab";
String str3=new String("ab");
String str4=new String("ab");
System.out.println(str3==str4);//false
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true

因为str3与str4的字符串的值是相同的,所以str3.equals(str4)为true,但是由于str3与str4指向的不是同一个对象,所以str3==str4返回是false。同样因为str1与str3字符串的值是相同的,尽管str1与str3指向的不是同一个对象,str1.equals(str3)同样返回的是true

实验六:

 String str1="ab";
String str3=new String("ab");
String str4=new String("ab");
String str5=str3;
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true
System.out.println(str3.equals(str5));//true
System.out.println(str4.equals(str5));//true
System.out.println(str3==str5);//true
System.out.println(str4==str5);//false
System.out.println(str1==str5);//false
System.out.println(str1.equals(str5));//true

这里将str3赋值给str5,所以str3与str5指向了同一对象,这样str3==str5返回为true值,str3.equals(str5)同样返回true值。由于str4与str5指向的不是同一对象,所以str4==str5返回false。但是也是因为字符串的值是相同的,所以str4.euqals(str5)返回为true值。

下面是以上实验所有的代码:

 public class Test
{
public static void main(String[] args)
{
String str1="ab";
String str2="abc";
String str6=str2;
String str3=new String("ab");
String str4=new String("ab");
String str5=str3;
System.out.println(str1==str6);//true
System.out.println(str2==str6);//true
System.out.println(str1.equals(str6));//true
System.out.println(str2.equals(str6));//true
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true
System.out.println(str3==str4);//false
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true
System.out.println(str3.equals(str5));//true
System.out.println(str4.equals(str5));//true
System.out.println(str3==str5);//true
System.out.println(str4==str5);//false
System.out.println(str1==str5);//false
System.out.println(str1.equals(str5));//true
}
}

将String类换成Integer包装类,测试代码及结果如下:

 class TestNumber
{
public static void main(String[] args)
{
Integer str1=23;
Integer str2=23;
Integer str6=str2;
Integer str3=new Integer(23);
Integer str4=new Integer(23);
Integer str5=str3;
System.out.println(str1==str6);//true
System.out.println(str2==str6);//true
System.out.println(str1.equals(str6));//true
System.out.println(str2.equals(str6));//true
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true
System.out.println(str3==str4);//false
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true
System.out.println(str3.equals(str5));//true
System.out.println(str4.equals(str5));//true
System.out.println(str3==str5);//true
System.out.println(str4==str5);//false
}
}

补充说明:

Integer类的equals源码

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

可见,Integer中的equals中的是直接取得数值进行比较

而String中的equals源码如下:

 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;
}

可见,String类中的源码与Integer中的有所不同,不同之处在于先采用了==方式进行比较,如果不是同一个对象再比较值,可见这个equals函数适用于存储在常量池中的字符串,例如

 String str1="ab";
String str2="ab";
System.out.println(str1.equals(str2));

str1与str2的比较equals方法中的

 if (this == anObject) {
return true;
}

进行比较得出的true

而下面的例子:

 String str3=new String("ab");
String str4=new String("ab");
System.out.println(str3.equals(str4));

str3与str4由于不是同一对象,所以if(this==anObject)不符合条件,所以进行下面字符串值的比较,最后返回true

下面的例子同理

String str5="abc";
String str6=new String("abc");
System.out.println(str5.equals(str6));

但这里还有一个陷阱,就是Integer类,可以参考这个类的源码,知道了Integer类缓存了-128到127,官方的解释是小的数字使用的频率比较高,超过这个范围的时候就会执行new Integer,可见如下代码

Integer a=1000;
Integer b=1000;
System.out.println(a==b);//false;

是正确的

但是一旦两个变量a与b被赋值为100,结果就是true

如下代码:

Integer a=new Integer(1000);
int b=1000;
Integer c=new Integer(1000);
Integer d=new Integer(1000);
System.out.println(a==b);//true
System.out.println(c==d);//false 

由于c与d是new Integer得到的结果,并没有使用缓存,所以c与d并不是同一个对象,输出的结果是false

但是a与b为什么是true呢?

因为Integer与int进行==比较的时候,java会把Integer自动拆箱,转为int类型,这样就a与b就指向了同一对象,所以会输出true

关于java中equals与==的区别的小实验的更多相关文章

  1. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  2. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  3. java中.equals和==的区别?

    Java中的equals是十分重要的,和= =要区别开来,孙卫琴的JAVA面向对象编程一书对这个做了阐述,现在小结其主要内容,而且要将 = =和 equals列为重要的对比概念来学习 1.声明格式   ...

  4. (转)Java中equals和==的区别

    java中的数据类型,可分为两类:  1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean    他们之间的比较,应用双等号( ...

  5. Java 中 Equals和==的区别(转)

    另外一篇参考: https://blog.csdn.net/striverli/article/details/52997927 在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的 ...

  6. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...

  7. java中equals和==的区别详解

    java中的数据类型,可分为两类: 1.基本数据类型. byte,short,char,int,long,float,double,boolean这八大原始数据类型他们之间的比较,使用“==”,比较的 ...

  8. java中equals和"=="的区别

    "=="号,它比较的是一个对象在内存中的地址值, 比如2个字符串对象String s1 = new String("str");String s2 = new ...

  9. Java中equals和“==””的区别,String特殊

    public class TestString { /* * java中的数据类型,可分为两类: * 1.基本数据类型,也称为原始数据类型.byte,short,char,int,long,float ...

随机推荐

  1. 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)

    [BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...

  2. Linux内核的编译安装

    前言 Linux内核是Linux操作2347系统的核心,也是整个Linux功能体现的核心,就如同发动机在汽车中的重要性.内核主要功能包括进程管理.内存管理.文件管理.设备管理.网络管理等.Linux内 ...

  3. 20179209《Linux内核原理与分析》第一周作业

    如何揭开Linux操作系统的最大面纱 个人认为,真正理解一个操作系统最根本的就是理解其文件系统结构. 自windows图形界面诞生,国内大多数用户都选择了windows操作系统,很多人觉得window ...

  4. 我的Java开发学习之旅------>Java经典排序算法之归并排序

    一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列 ...

  5. vuex原理笔记

    本文总结自: https://tech.meituan.com/vuex-code-analysis.html, 将要点提炼为笔记,以便不时之需,安不忘危. 核心可分为两部分: 1.vue.use(V ...

  6. GPS NMEA-0183协议介绍【转】

    本文转载自:http://blog.csdn.net/haofeng82/article/details/4439349 找到的一篇关于GPS常用的一种协议的介绍,希望对大家有用 NMEA-0183 ...

  7. UVA - 11475 Extend to Palindrome —— 字符串哈希 or KMP or 后缀数组

    题目链接:https://vjudge.net/problem/UVA-11475 题意: 给出一个字符串,问在该字符串后面至少添加几个字符,使得其成为回文串,并输出该回文串. 题解: 实际上是求该字 ...

  8. dotnet core on Linux 环境搭建及入门demo

    首先感谢张善友大大提供的腾讯云实验室链接(https://www.qcloud.com/developer/labs/list). 以下是整个搭建过程及简单demo实例 1.搭建 .NET Core ...

  9. consider increasing the maximum size of the cache.

    虚拟机上搭建jenkins,出现unable to free [10] percent of the cache for Context [/jenkins] 提示让我加大缓存 consider in ...

  10. IE不支持HTML5表单属性placeholder的解决办法

    1. [代码][JavaScript]代码 (function ($) {    $.fn.placeholder = function (options) {        var defaults ...