值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。

equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

==比较的是2个对象的地址,而equals比较的是2个对象的内容。

显然,当equals为true时,==不一定为true;

一、String中的equals和==

1、

public class TestString {

public static void main(String[] args) {

String s1 = "Monday";

String s2 = "Monday";

}

}

上面这段程序中,到底有几个对象呢?

来检测一下吧,稍微改动一下程序

public class TestString {

public static void main(String[] args) {

String s1 = "Monday";

String s2 = "Monday";

if (s1 == s2)

System.out.println("s1 == s2");

else

System.out.println("s1 != s2");

}

}

编译并运行程序,输出:s1 == s2说明:s1 与 s2 引用同一个 String 对象 -- "Monday"!

2.再稍微改动一下程序,会有更奇怪的发现:

public class TestString {

public static void main(String[] args) {

String s1 = "Monday";

String s2 = new String("Monday");

if (s1 == s2)

System.out.println("s1 == s2");

else

System.out.println("s1 != s2");

if (s1.equals(s2)) System.out.println("s1 equals s2");

else

System.out.println("s1 not equals s2");

}

}

我们将s2用new操作符创建

程序输出:

s1 != s2

s1 equals s2

说明:s1 s2分别引用了两个"Monday"String对象

3. 字符串缓冲池

原来,程序在运行的时候会创建一个字符串缓冲池当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1

将s2引用s1所引用的对象"Monday"

第二段程序中,使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创建在内存中。他们的值相同,但是位置不同,一个在池中游泳一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?

4.

再次更改程序:

public class TestString {

public static void main(String[] args) {

String s1 = "Monday";

String s2 = new String("Monday");

s2 = s2.intern();

if (s1 == s2)

System.out.println("s1 == s2");

else

System.out.println("s1 != s2");

if (s1.equals(s2)) System.out.println("s1 equals s2");

else

System.out.println("s1 not equals s2");

}

}

这次加入:s2 = s2.intern();

程序输出:

s1 == s2

s1 equals s2

原来,(java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。

更好的办法:

把所有的String都intern()到缓冲池去吧

最好在用到new的时候就进行这个操作

String s2 = new String("Monday").intern();

然后就可以用==比较两个字符串的值了

二、简单数据类型和封装类中的equals和==

Java为每一个简单数据类型提供了一个封装类,每个基本数据类型可以封装成对象类型。

除int(Integer)和char(Character),其余类型首字母大写即成封装类类型名。double (Double), float(Float),long(Long), short(Short),byte(Byte),boolean(Boolean).

以int和Integer为例说明

Java中int和Integer区别如下:

1.int是基本的数据类型,默认值可以为0;2.Integer是int的封装类,默认值为null;3.int和Integer都可以表示某一个数值;4.int和Integer不能够互用,因为他们两种不同的数据类型;

int a1=1;

int a2=1;

Integer b1 =new Integer (1);

Integer b2 =new Integer (1);

------------------------------

a1==a2 这个是成立的,很简单,都知道a1==b1 这个是不成立的.表达式的值为 false ,它们是不同的数据类型b1==b2 这个也是不成立的.表达式的值为 false,虽然是相同的数据类型,但是它们是两个对象,==比较的是2个对象的地址,它们的地址是不相等的,内容相等都是1;

b1.equals(b2)==true 这个是成立的,表达式的值为 true. 相同数据类型,两个对象,地址不同,内容相同, quals比较的是2个对象的内容,所以成立。

(a.equals(b),因为equals比较的是两个对象,所以a,b都不能为基本数据类型,否则会出编译错误。)同理,其它的封装类和基本类型也是这样的.

java中equals和==的区别

==比较的是2个对象的地址,而equals比较的是2个对象的内容。

三、其他类怎么使用equals和==

API里的类大部分都重写了equals方法,没有重写的一般是自己写的类,如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的,你可以看源码。

四、java里equals和hashCode之间什么关系

只是为了维护 hashCode 方法的常规协定,才要求用equals比较的两个对象的hashCode相同. equals()和hashCode()都来自java.lang.Object.你当然可以重写.

比如a.equals(b).仅当a的内存地址相等时,才返回true.当然如String等类已经对这个方法进行了重写,比较的就不再是内存地址了. hashCode()的值也是与内存地址相关的.所以仅当内存地址相等时,hashCode才相等.

同样很多类也重写了这个方法,还是以String为例:

public int hashCode() {

int h = hash;

if (h == 0) {

int off = offset;

char val[] = value;

int len = count;

for (int i = 0; i < len; i++) {

h = 31*h + val[off++];

}

hash = h;

}

return h;

}

就不在与内存地址相关了.这样做是为了保证用equals比较返回为true的两个对象,他们的hashCode是相同的.

所以一般重写equals的时候都会重写hashCode().当然,这个相当于一个约定,一个协议.你不这么做并不会错.

五、hashCode

在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。

所以这里要匹配2部分,hashcode和equals但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。。。

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

  1. java中ArrayList 、LinkList区别

    转自:http://blog.csdn.net/wuchuanpingstone/article/details/6678653 个人建议:以下这篇文章,是从例子说明的方式,解释ArrayList.L ...

  2. java 中 ==和equals 的区别

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

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

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

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

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

  5. java中a++与++a区别

    java中a++与++a区别 a++与++a的区别,如果单独使用没有任何区别,如果在运算中就有区别了,a++是先运算在赋值,而++a是先赋值在运算!! 先看a++的代码哦 class demo1 { ...

  6. c#与java中byte字节的区别及转换方法

    原文:c#与java中byte字节的区别及转换方法 在java中  byte的范围在 [-128,127] 在C#中  byte的范围在 [0,255] 所以 java程序与C#程序 进行数据传输的时 ...

  7. Java中的“&”和“&&”的区别

    Java中的"&"和"&&"的区别 1."&"是位运算符,"&&"是逻辑 ...

  8. java中PriorityBlockingQueue 和DelayedWorkQueue 区别

    java中PriorityBlockingQueue 和DelayedWorkQueue 区别

  9. Java-杂项: Java中Array和ArrayList区别

    ylbtech-Java-杂项: Java中Array和ArrayList区别 1.返回顶部 1. 1)精辟阐述:可以将 ArrayList想象成一种“会自动扩增容量的Array”. 2)Array( ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本)2017.4.22

    昨天来不及编写,这是4月22日的日志,现在补上. 1.开完站立式会议后的合照 2.任务分解图 3.开会讨论的结果,任务分派 队员 今日进展 明日安排 陈鑫龙 原型设计图分析,设计登陆界面原稿 实现登陆 ...

  2. 201521123026《Java程序设计》第2周学习总结

    1. 本章学习收获 1.熟悉了码云的部分功能的使用 2.java编程基础的巩固以及延伸 3.解决了部分PTA编程时所遇到困难并明白了解决困难的方法的原理 4.了解了用package和import管理类 ...

  3. 《JAVA程序设计》第10周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fin ...

  4. 201521123096《Java程序设计》第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  5. web前端 学习线路

    1. 前言 大约在几个月之前,让我看完了<webkit技术内幕>这本书的时候,突然有了一个想法.想把整个web前端开发所需要的知识都之中在一个视图中,形成一个完整的web前端知识体系,目的 ...

  6. panda库------对数据进行操作---合并,转换,拼接

    >>> frame2 addr age name 0 beijing 12 zhang 1 shanghai 24 li 2 hangzhou 24 cao >>> ...

  7. GCD之全局、主线程

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 -(NSString *)fetchData {     [NSThread sleepFo ...

  8. Spring 具名参数NamedParameterJdbcTemplate

    具名参数: 具名参数:SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代 我们之前一直是用JDBCTemplate  进行 ...

  9. 【转】Spark运行过程

    http://www.cnblogs.com/1130136248wlxk/articles/6289717.html

  10. uvalive 3135 Argus

    https://vjudge.net/problem/UVALive-3135 题意: 有一个系统有多个指令,每个指令产生一个编号为qnum的时间,每个指令的触发间隔不相同,现在给出若干个指令,现在的 ...