“==”的作用:

判断两个变量栈内存中存储的值是否相等,如果相等返回true,如果不相等返回false。

有两种形式的比较需要用到比较运算符“==”,一是两个基本数据类型之间的比较,二是两个引用数据类型之间的比较。

1.两个基本数据类型之间的比较:

  八大基本数据类型:byte,short,int,long,double,folat,boolean,char,其中占一个字节的是byte和boolean,short和char占两个字节,int,float占四个字节,double和long占8个字节,这八种数据变量中直接存储其值,变量是在栈中存储的。

  因此:“==”比较基本数据类型时,比较的是值。

  JAVA 基本数据类型创建单个变量是不可以new的,因为new的都是对象。但创建基本数据类型数组时可以new,因为数组是对象。

int a = 5;
int b = 5;
int c = 6;
System.out.println(a == b);  // 5 == 5
System.out.println(a == c);  // 5 == 6

  创建了是三个基本数据类型的变量,他们在栈中存储的值就是其数值本身,栈中值由低到高依次为a(5)、b(5)、c(6)。因此“a==b”其本质就是“5==5”,返回true;“a==c”其本质就是“5==6”,返回false。

  因此,运行结果依次为:true  false。

2.两个引用数据类型之间的比较:

  引用数据类型都是对象,一般都是在堆中被创建,变量中存储的是堆中对象的地址引用。

  因此,“==”比较引用类型时,比较的是地址。

  • 一般的类用new来创建对象,是在堆中开辟空间来存储的,每个对象都有唯一的地址;
  • 数据类型的包装类既可以用new来创建,在堆中开辟空间存储,也可以直接创建,通过自动装箱的机制来完成对象在堆中的创建。

  这里要注意两个数据类型,一个是String类型,一个是Integer类型。具体请看案例分析:

String str1 = new String("abc");    // 0x123
String str2 = new String("abc");    // 0x262
String str3 = new String("xyz");    // 0x762
System.out.println(str1 == str2);  // 0x123 == 0x262
System.out.println(str1 == str3);  // 0x123 == 0x762

  用new创建了三个String类型的对象,创建的三个对象都在堆中,因此有不同的地址引用。三个变量在栈中存储的是三个对象的地址引用,其值各不相同。

  因此,运行结果依次为:false false。

String str1 = "abc";    // 0x111  
String str2 = "abc";    // 0x111
String str3 = "xyz";    // 0x123
System.out.println(str1 == str2);  // 0x111 == 0x111
System.out.println(str1 == str3);  // 0x111 == 0x123

  直接创建了三个String类型的对象,创建的字符串在字符串常量池中,因此创建已经存在的字符串会直接返回其地址引用。str2在栈中存储的值和str1在栈中存储的值是一样的,都是字符串“abc”在字符串常量池中的地址引用,而str3在栈中存储的是字符串“xyz”在字符串常量池中的地址引用。

  因此,运行结果一次为:true  false。

Integer s1 = new Integer(100);
Integer s2 = new Integer(100);
Integer s3 = new Integer(200);
System.out.println(s1 == s2);
System.out.println(s1 == s3);

  用new创建了三个Integer类型的对象,创建的三个对象都在堆中,因此有不同的地址引用。三个变量在栈中存储的是三个对象的地址引用,其值各不相同。

  因此,运行结果依次为:false false。

Integer n1 = 100;
Integer n2 = 100;
System.out.println(n1 == n2); Integer a1 = new Integer(100);
Integer a2 = new Integer(100);
System.out.println(a1 == a2); Integer m1 = 300;
Integer m2 = 300;
System.out.println(m1 == m2); Integer b1 = new Integer(300);
Integer b2 = new Integer(300);
System.out.println(b1 == b2);

  运行结果依次为:true  false  false false。为什么是这样呢?

  两个new的好解释,因为是在堆中创建的,每个对象有唯一的地址,因此会返回false。但第一个和第三个是啥情况呢?

  这是因为在Java中为了提高空间和时间性能,Integer类中有一个静态内部类IntegerCache,在IntegerCache类中有一个Integer数组,用以缓存当数值范围为[-128,127]时的Integer对象。所以在自动装箱的过程中,如果数值在[-128,127]内,会直接返回其地址引用,若是不在才在堆中创建对象。

equals的作用:

  在Java中许多系统提供的类都定义了equals方法,这个方法用来比较两个独立对象的内容是否相同,而不是比较引用值本身的。自定义方法的定义大致如下(以String类为例):

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (!COMPACT_STRINGS || this.coder == aString.coder) {
return StringLatin1.equals(value, aString.value);
}
}
return false;
}

  但是,如果一个自定义的类中没有定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法定义如下:

public boolean equals(Object obj) {
return (this == obj);
}

  可以看到,如果一个类中没有显式的定义equals方法,那么equals方法的作用和“==”的作用是一样的,都是比较两个变量指向的对象是否是同一对象。

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

  “==”比较的是地址,str1和str2在堆中的地址是不一样的,因此结果返回false,因为String类型自定义了equals方法,此equals方法比较的是对象的内容,因此结果返回true。

  所以运行结果依次为false   true。

public class Test {
public Test() {}
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
Test c = a;
System.out.println(a.equals(b));
System.out.println(a.equals(c));
}
}

  自己定义的的Test类,并没有自定义equals方法,因此euqals方法和“==”的作用是一样的,比较的是对象的地址,也就是说判断两个对象是否是同一个。a和b中存储的地址分别是两个不同对象的地址,c被赋值了a中存储的地址,也就是说a和c指向的是同一个对象。

  因此,运行结果依次是:false   true。

总结一下:

  运算符“==”只是用来比较两个变量在栈中存放的值是否相同。

  equals是类的成员方法,一般用来比较两个独立对象的内容是否相同(要看具体的定义)。如果自定义的类中没有定义equals方法,则会继承Object类的equals方法,其作用与“==”相同。

Java中“==”和 equals的区别的更多相关文章

  1. java 中 ==和equals 的区别

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

  2. JAVA中“==”与equals()方法区别

    equals 方法是 java.lang.Object 类的方法 有两种用法说明: ()对于字符串变量来说,使用"=="和"equals()"方法比较字符串时, ...

  3. Java中==与equals的区别及理解

    区别: "==" 比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间),也就是说在内存空间中的存储位置是否一致. 如果两个对象的引用相同时(指向同一对象时)," ...

  4. Java中==与equals()的区别

    声明转载来源:http://blog.csdn.net/striverli/article/details/52997927 ==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系 ...

  5. java 中 “==” 和 equals 的区别

    转自https://www.cnblogs.com/www123----/p/7857298.html 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new Strin ...

  6. Java 中 == 和 equals 的区别

    有一段时间,== 和 equals 的区别一直困扰着我.因为涉及到Java的内存机制,然而Java的内存机制又是比较抽象的东西,所以对那时候的我来说,实在是很难理解. == 和 equals 最大的区 ...

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

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

  8. JAVA中==与equals的区别

    equals如果没有被重写的话,和==的作用是一样的,都是判断两个对象引用是否指向同一个地址.一般重写了equals()方法就表示比较它们“实际意义上相等”,比较的是内容,而不是引用地址.Java中S ...

  9. Java中==和equals()的区别

  10. Java中“==”与equals的区别以及equals方法的重写

    一.“==”与equals的区别: (1)==代表比较双方是否相同: 基本数据类型表示值相等. 引用数据类型表示地址相等,即同一个对象. (2)Object中的equals()方法:是否为同一个对象的 ...

随机推荐

  1. 在 Go 语言中,我为什么使用接口

    强调一下是我个人的见解以及接口在 Go 语言中的意义. 如果您写代码已经有了一段时间,我可能不需要过多解释接口所带来的好处,但是在深入探讨 Go 语言中的接口前,我想花一两分钟先来简单介绍一下接口. ...

  2. JDK1.8源码学习-HashMap

    JDK1.8源码学习-HashMap 目录 一.HashMap简介 HashMap 主要用来存放键值对,它是基于哈希表的Map接口实现的,是常用的Java集合之一. 我们都知道在JDK1.8 之前 的 ...

  3. 0x01 基本算法-位运算 a^b

    #include<bits/stdc++.h>using namespace std;int power(int a, int b, int p){    int ans = 1%p;   ...

  4. fatal error: glib.h: No such file or directory

    在学习BLE bluez的时候,做了一个测试程序,看到gatttool.c下面有一个glib解析命令行的功能,想移植到自己的程序接口中,但是添加了#include <glib.h>后,出现 ...

  5. NumPy笔记-ndarray

    ndarray,N维数组对象(矩阵) 所有元素必须是相同类型 ndim属性,维度个数 shape属性,各维度大小 dtype属性,数据类型 创建ndarray np.array(collection) ...

  6. 模拟画图题P1185 绘制二叉树

      题目链接P1185 绘制二叉树 题意概述   根据规则绘制一棵被删去部分节点的满二叉树.节点用 \(o\) 表示,树枝用/\表示.每一层树枝长度会变化,以满足叶子结点有如下特定: 相邻叶子节点是兄 ...

  7. iOS多线程之GCD、OperationQueue 对比和实践记录

    [toc] 简介      在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的.但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大时钟速度.因此,芯片制 ...

  8. python实现对列表的增删查修操作

    #定义一个空列表 list_demo=[] #1,向列表中插入元素 def append_demo(): #第一种使用append,可以在列表末尾添加一个函数 for i in range(2): l ...

  9. 轻轻松松学CSS:float

    float属性,会使元素向左或向右移动,其周围的元素也会重新排列.float不仅自己飘忽不定,还对周围元素有影响,这种影响力不容小觑.他捉摸不定(浮动规律不好把握),他干涉他国内政(对周围元素有影响) ...

  10. 硬盘网盘U盘全部可以丢掉了,这个设备可以让你享受随身带着几个T的感受

    前言 有小伙伴问我,你怎么老写技术类文章,能不能写点别的. 其实我兴趣挺广泛的,早年还有机会做个游戏博主,可惜最近2年金盆洗手了.戒了手游,ns和ps4都在吃灰.能完整玩完的游戏屈指可数.但是对于折腾 ...