博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java面试——从JVM角度比较equals和==的区别
阅读量:7205 次
发布时间:2019-06-29

本文共 2132 字,大约阅读时间需要 7 分钟。

hot3.png

1.  Java中数据类型分类

1.1    基本数据类型

又称为原始数据类型,byte,short,char,int,long,float,double,boolean,他们之间的比较应该使用(==),比较的是他们的值。

 

1.2    复合数据类型

当复合数据类型用(==)进行比较,比较的是他们在内存中的存放地址。

当复合数据类型之间进行equals比较时,这个方法的初始行为是比较对象在堆内存中的地址,但在一些诸如String,Integer,Date类中把Object中的这个方法覆盖了,作用被覆盖为比较内容是否相同。

本文原创,转载请注明出处:

 

2.  String类的讨论

 

[java]  

  1. String s1 = "Hello";  
  2. String s2 = "Hello";  
  3. if (s1 == s2){  
  4.  System.out.println("s1 == s2");  
  5. }else{  
  6. System.out.println("s1 != s2");  
  7. }  

输出:s1 == s2

 

说明:双等号在进行复合数据类型比较时,比较的是内存中的存放地址。因此s1与s2引用同一个String对象。

 

[java]  

  1. String s1 = "Hello";  
  2. String s2 = new String("Hello");  
  3. if (s1 == s2){  
  4. System.out.println("s1 == s2");  
  5. }else{  
  6. System.out.println("s1 != s2");  
  7. }  
  8. if (s1.equals(s2)) {  
  9. System.out.println("s1 equals s2");  
  10. }else{  
  11. System.out.println("s1 not equals s2");  
  12. }  

 

输出:

s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个对象。显然,两者内容是相同的,因此equal返回true。第一个例子也一样。

我们接下来将详细讨论,为什么在上面两个例子中,s1和s2出现了两种不同的指向对象的情况。

 

 

3.   解释

 

[java]  

  1. String str = new String("abc");   
  2. String str = "abc";   

 

两种的形式来创建,第一种是用new()来新建对象的,那么这种情况的内存是怎么分配的呢,答案是在堆空间和字符串常量池中。每调用一次就会在堆中创建一个新的对象,如果常量池中已经存在"abc",那么就不会额外在常量池中生成引用。因此这句话会产生一个或者两个对象。

而第二种是先在常量池中创建一个对String类的对象引用变量str,然后查找常量池中有没有存放"abc",如果没有,则将"abc"存放并令str指向”abc”,如果已经有”abc”则直接令str指向“abc”。 

由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。 

具体可以查看此篇。

 

4.  String类的intern方法

[java]  

  1. String s1 = "Hello";  
  2. String s2 = new String("Hello");  
  3. s2 = s2.intern();  
  4. if (s1 == s2){  
  5. System.out.println("s1 == s2");  
  6. }else{  
  7. System.out.println("s1 != s2");  
  8. }  
  9. if (s1.equals(s2)) {  
  10. System.out.println("s1 equals s2");  
  11. }else{  
  12. System.out.println("s1 not equals s2");  
  13. }  

程序输出:

s1 == s2
s1 equals s2
这次加入:s2 = s2.intern(),java.lang.String的intern()方法,"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。但是这也仅仅是JDK1.6以及以前的过时的处理方法,如果想了解更全更清晰的intern()方法,请务必参考我的这篇博文。

 

5.  为什么Java1000==1000false100==100true

 

[java]  

  1. Integer i1 = 100,i2 = 100;  
  2. System.out.println(i1==i2);  
  3. Integer i3 = 1000,i4 = 1000;  
  4. System.out.println(i3==i4);  

 

 

 

查看Integer.java类,会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。

所以例子中i1和i2指向了一个对象。因此100==100为true。

转载于:https://my.oschina.net/newchaos/blog/1579560

你可能感兴趣的文章
页面渲染的同步和异步区别?
查看>>
MongoDB基本使用
查看>>
[转]Eclipse中远程调试Hadoop
查看>>
由一个C语言递归判断回文数的程序产生的回忆
查看>>
Linux下安装mysql5.7
查看>>
1.1.3 Getting Started_Budding Your First App_Building a Simple User Interface
查看>>
学习日记0907 GIL全局解释器锁 死锁与递归锁 信号量 Event事件 线程的queue
查看>>
linux awk函数
查看>>
性能测试
查看>>
阿里云服务器Linux CentOS安装配置(六)resin多端口配置、安装、部署
查看>>
jQuery对象与DOM对象之间的转换(转)
查看>>
asp.net跳转页面的三种方法比较
查看>>
Bzoj1076 [SCOI2008]奖励关
查看>>
JCo 指南
查看>>
git使用--pull代码时冲突
查看>>
1-3-1动态随屏幕变化而变化
查看>>
Reading papers_6(Pattern Recognition And Machine Learning一书,ing...)
查看>>
java mybatis 新增记录 与 insertSelective 保存问题
查看>>
cocos2d-x 搭建android开发环境记录
查看>>
列表与元组的区别
查看>>