equals是Object类的公共方法,方法内部是用==实现的。但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同。而==是比较地址,但是基本数据类型,==比较的是两个变量的值是否相同,对于两个引用数据类型而言,==比较的是它们的地址是否相同。

equals方法比较内容

public class CSDN {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println("String:" + s1.equals(s2) + "," + s1.equals(s3)); Byte a1 = new Byte((byte)1);
Byte b1 = new Byte((byte)1);
System.out.println("Byte:" + a1.equals(b1)); Short a2 = new Short((short)1);
Short b2 = new Short((short)1);
System.out.println("Short:" + a2.equals(b2)); Integer a3 = new Integer(1);
Integer b3 = new Integer(1);
System.out.println("Integer:" + a3.equals(b3)); Long a4 = new Long(1L);
Long b4 = new Long(1L);
System.out.println("Long:" + a4.equals(b4)); Float a5 = new Float(1.0f);
Float b5 = new Float(1.0f);
System.out.println("Float:" + a5.equals(b5)); Double a6 = new Double(1.0d);
Double b6 = new Double(1.0d);
System.out.println("Double:" + a6.equals(b6)); Boolean a7 = new Boolean(false);
Boolean b7 = new Boolean(false);
System.out.println("Boolean:" + a7.equals(b7)); Character a8 = new Character('1');
Character b8 = new Character('1');
System.out.println("Character:" + a8.equals(b8));
}
} 输出:
String:true,true
Byte:true
Short:true
Integer:true
Long:true
Float:true
Double:true
Boolean:true
Character:true

==比较地址

1. 对于基本数据类型是比较它们的值,下面用int类型举例演示,其他基本数据类型一样的结果。

public class CSDN {
public static void main(String[] args) {
int a = 1;
int b = 1;
System.out.println(a == b);
}
} 输出:
true

2. 对于引用数据类型,比较的是对象的地址是否相同。由于java的常量池机制,相同的字符串常量地址是一样的。

public class CSDN {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println("String:" + (s1==s2) + "," + (s1==s3) + "," + (s3==s4)); Byte a1 = new Byte((byte)1);
Byte b1 = new Byte((byte)1);
System.out.println("Byte:" + (a1==b1)); Short a2 = new Short((short)1);
Short b2 = new Short((short)1);
System.out.println("Short:" + (a2==b2)); Integer a3 = new Integer(1);
Integer b3 = new Integer(1);
System.out.println("Integer:" + (a3==b3)); Long a4 = new Long(1L);
Long b4 = new Long(1L);
System.out.println("Long:" + (a4==b4)); Float a5 = new Float(1.0f);
Float b5 = new Float(1.0f);
System.out.println("Float:" + (a5==b5)); Double a6 = new Double(1.0d);
Double b6 = new Double(1.0d);
System.out.println("Double:" + (a6==b6)); Boolean a7 = new Boolean(false);
Boolean b7 = new Boolean(false);
System.out.println("Boolean:" + (a7==b7)); Character a8 = new Character('1');
Character b8 = new Character('1');
System.out.println("Character:" + (a8==b8)); }
} 输出:
String:true,false,false
Byte:false
Short:false
Integer:false
Long:false
Float:false
Double:false
Boolean:false
Character:false

解释下第一行输出的结果:由于java的常量池机制,s1和s2它们在常量池的地址是一样的。而s3是new出来的,需要在堆内存开辟空间,地址当然和s1,s2的不一样。

下面看下几个拆箱装箱的例子

public class CSDN {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
int c = 100;
Integer d = new Integer(100); System.out.println("a == b :" + (a == b)); //a和b装箱,然后比较地址。
System.out.println("a.equals(b) :" + a.equals(b)); //a和b装箱,然后比较对象内容
System.out.println("a == c :" + (a == c)); // a先拆箱,然后再和c比较值
System.out.println("a.equals(c) :" + a.equals(c)); //c先装箱,然后比较对象内容
System.out.println("a == d :" + (a == d)); //d属于new出来的,地址和a肯定不一样
System.out.println("a.equals(d) :" + a.equals(d)); //a装箱,然后和d比较内容
System.out.println("d == c :" + (d == c)); //d拆箱,然后和c比较值
System.out.println("d.equals(c) :" + d.equals(c)); //c装箱,然后和d比较内容 }
} 输出:
a == b :true
a.equals(b) :true
a == c :true
a.equals(c) :true
a == d :false
a.equals(d) :true
d == c :true
d.equals(c) :true

简单来说,装箱就是将基本数据类型转换为包装器类型;拆箱就是将包装器类型转换为基本数据类型。

例如:

public class CSDN {
public static void main(String[] args) {
Integer a1 = 100; //自动装箱,相当于执行Integer a1 = Integer.valueOf(100);
int b1 = a1; //自动拆箱,相当于执行int b1 = a1.intValue();
}
}

其中Integer.valueOf函数源码如下:

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

而cache[]源码如下:数组中保存的是256个Integer对象。

static final Integer cache[] = new Integer[256];

也就是说,只要在自动装箱的过程中,值在-128到127之间,那么它们==的地址都是一样的。例如最上面的例子中下面这行代码:

System.out.println("a == b :" + (a == b)); //a和b装箱,然后比较地址。

如果值超过这个范围,那么在自动装箱时就会再开辟空间,地址就会不一样。例如:

public class CSDN {
public static void main(String[] args) {
Integer a = 128;
Integer b = 128;
System.out.println(a == b);
System.out.println(a.equals(b));
}
} 输出:
false
true

如果不理解就看看源码!

java中的equals与==的区别的更多相关文章

  1. Java中“==”与equals方法的区别

    1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...

  2. java中“==”和equals方法的区别,再加上特殊的String引用类型

    ==和equals的区别: 1.==是运算符,而equals是基类Object定义的一个方法,并且equals使用==定义的 2.进行比较时,分为  基本数据类型  的比较和  引用数据类型 的比较 ...

  3. Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法

    一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...

  4. java中 ==与equals 有什么区别?

    1.==既可以比较基本类型变量,又可比较引用类型变量,而equals只能比较引用类型变量: 2.equals方法支持重写,如果未重写equals方法,则比较引用变量时与==都是比较变量所指向的对象地址 ...

  5. Java中"String.equals()“和"=="的区别

    Do NOT use the `==`` operator to test whether two strings are equal! It only determines whether or n ...

  6. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  7. 【Java学习笔记之二十九】Java中的"equals"和"=="的用法及区别

    Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: String str1 = new String(" ...

  8. 【转】彻底弄懂Java中的equals()方法以及与"=="的区别

    彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差. ...

  9. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

随机推荐

  1. [coci2015-2016 coii] Palinilap【字符串 哈希】

    传送门:http://www.hsin.hr/coci/archive/2015_2016/ 进去之后点底下的那个.顺带说一句,题目既不是一个英文单词,也不是克罗地亚单词,估计只是从回文串的英文单词p ...

  2. bzoj2740 串 && bzoj2176 strange string(最小表示法模板)

    https://konnyakuxzy.github.io/BZPRO/JudgeOnline/2740.html 题解讲的很清楚了 (好像等于的情况应该归入case2而不是case1?并不确定) 具 ...

  3. sourceTree免注册免登陆使用方法-Windows

    安装sourceTree需要注册Google账号,而现在国内注册账号需要FQ,超级麻烦,所以还是免注册的号. 处理方法: 解决办法 在目录C:\Users\{youruser}\AppData\Loc ...

  4. 常用验证函数isset()/empty()/is_numeric()函数

    1) isset()用来检查变量是否设置,若变量存在且值不为NULL时为TRUE: 检查多个变量时变量要全部存在且值不为NULL时为TRUE: 若用函数unset()释放后再用isset()检测时为F ...

  5. PaaS优点与限制(3)

    PaaS优点与限制(3) PaaS学习笔记目录 PaaS基础学习(1) 在PaaS上开发Web.移动应用(2) PaaS优点与限制(3) 13. PaaS的核心服务 核心服务是指提供数据存储.SQl. ...

  6. Android用Intent来启动Service报“java.lang.IllegalArgumentException: Service Intent must be explicit”错误的解决方法

    今天没事来写个播放器,照搬书上的原句,其中一句 //用于启动和停止service的Intent final Intent it = new Intent("android.mu.action ...

  7. 查询sqlserver数据库,表占用数据大小

     if exists(select 1 from tempdb..sysobjects where id=object_id('tempdb..#tabName') and xtype='u')dro ...

  8. 使用Cordova将您的前端JavaScript应用打包成手机原生应用

    假设我用JavaScript和HTML开发了一个前端应用,我想把该应用打包成能直接在手机上安装和运行(不通过浏览器)的原生应用,例如像下面这样.对应用的用户来说,他们得到的用户体验和真正的用Andro ...

  9. 数据倾斜是多么痛?spark作业调优秘籍

    目录视图 摘要视图 订阅 [观点]物联网与大数据将助推工业应用的崛起,你认同么?      CSDN日报20170703——<从高考到程序员——我一直在寻找答案>      [直播]探究L ...

  10. urllib基础-构造请求对象,设置用户代理User-Agent

    有的网页具有一些反爬机制,如:需要浏览器请求头中的User-Agent.User-Agent类似浏览器的身份证. 程序中不设置User-Agent.默认是Python-urllib/3.5.这样网站就 ...