强烈推荐浅谈Java中String.equals()和==的区别
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了强烈推荐浅谈Java中String.equals()和==的区别相关的知识,希望对你有一定的参考价值。
浅谈Java中String.equals和==的区别
1. 基本数据类型&引用类型
八大基本数据类型:Byte,short,int,long,double,folat,boolean,char
,其中占一个字节的是byte,short和char占两个字节,int,float占四个字节,double和long占8个字节,boolean只有true和false,这八种数据变量中直接存储值
八大基本数据类型对应着各自的封装类型,提供了更多的方法,且不进行初始化时值默认为空(基本数据类型必须初始化)
像String类型属于引用类型,变量中存储的是地址,对应的地址存储数据.
2. equals&==
2.1 "=="操作符的作用
一个比较基本数据类型,一个是比较引用数据类型。
-
双等号在比较引用类型的时候主要是比较地址(判断引用是否指向堆内存的同一块地址)。
-
双等号比较的是基本数据类型的时候,比较的是数据的值。
2.2 equals的作用
equals方法在比较引用类型的时候就是纯粹的比较值。
equals用于判断两个变量是否是对同一个对象的引用,即堆中的内容是否相同,返回值为布尔类型
3. 测试
3.1 String作为一个引用类型来使用
例子一:对象不同,内容相同,"=="返回false
,equals返回true
String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true
例子二:同一对象,"=="和equals结果相同
String s1 = new String("java");
String s2 = s1;
System.out.println(s1==s2); //true
System.out.println(s1.equals(s2)); //true
3.2 String作为一个基本类型来使用
如果值不相同,对象就不相同,所以"==" 和equals结果一样
例子一:对象不同,内容相同,"=="返回false,equals返回true
String s1 = "java";
String s2 = "java";
System.out.println(s1==s2); //true
System.out.println(s1.equals(s2)); //true
如果String缓冲池内不存在与其指定值相同的String对象,那么此时虚拟机将为此创建新的String对象,并存放在String缓冲池内。
如果String缓冲池内存在与其指定值相同的String对象,那么此时虚拟机将不为此创建新的String对象,而直接返回已存在的String对象的引用。
其他基本数据类型一样如此!
4. 剖析
一)JVM把内存划分成两种:一种是栈内存,一种是堆内存。
-
在函数中定义的一些基本类型的变量和对象的引用变量(变量名)都在函数的栈内存中分配。
-
当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
-
堆内存用来存放由new创建的对象(包括由基本类型包装起来的类:Integer、String、Double,实际上每个基本类型都有他的包装类)和数组。
二)Object类中的equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
可以看出Object类中equals方法是用==判断对象引用是否指向同一内存地址。
三)String类很特殊 ,String类对equals方法进行了重写,如下:
equals源码:
//我们知道在Java中,所有的类都是直接或者间接的继承Object类,所以这里传入一个Object类型会比较方便一些
public boolean equals(Object anObject) {
//就是说让s1和s2进行双等号比较,如何二者内存地址相同的话,就会跳出并返回true,如果地址不同,会执行下一个if判断
if (this == anObject) {
return true;
}
//instanceof是对传入值的类型的一个判断,即s2若是String类型的话,返回true,继续执行下面代码,如果不是,跳出返回false
if (anObject instanceof String) {
//把s2转化为String类型
String anotherString = (String)anObject;
//这里省略了this,n指的是s1的长度
int n = value.length;
//判断s1和s2的长度是否相同
if (n == anotherString.value.length) {
//把s1拆分一下,并且把拆分的结果放到v1这个字符数组里,即['m','e','n','g']
char v1[] = value;
//同理,把s2拆分放到数组v2里
char v2[] = anotherString.value;
int i = 0;
//将两个数组的值进行比较,如果有一个不同,则返回false
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
可以看出在String类中equals方法不仅可以用==判断对象的内存地址是否相等,相等则返回true。如果前面的判断不成立,接着判断括号内的对象上是否是String类型,接着判断两个字符串对象的的长度是否相等,最后判断内容是否相等,如果相等则返回true。
参考: Link
加油!
感谢!
努力!
以上是关于强烈推荐浅谈Java中String.equals()和==的区别的主要内容,如果未能解决你的问题,请参考以下文章
为什么强烈推荐 Java 程序员使用 Google Guava 编程