Java面试——从JVM角度比较equals和==的区别
1. Java中数据类型分类
1.1 基本数据类型
又称为原始数据类型,byte,short,char,int,long,float,double,boolean,他们之间的比较应该使用(==),比较的是他们的值。
1.2 复合数据类型
当复合数据类型用(==)进行比较,比较的是他们在内存中的存放地址。下面介绍equals方法。
在Java的Object类中定义了equals方法,当复合数据类型之间进行equals比较时,这个方法的初始行为是比较对象在堆内存中的地址,但在一些诸如String,Integer,Date类中这个方法被覆盖了,在这些类当中equals有其自身的实现,作用被覆盖为比较内容是否相同。
本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52089040
2. String类的讨论
String s1 = "Hello";
String s2 = "Hello";
if (s1 == s2){
System.out.println("s1 == s2");
}else{
System.out.println("s1 != s2");
}
输出:s1 == s2
说明:双等号在进行复合数据类型比较时,比较的是内存中的存放地址。因此s1与s2引用同一个String对象。
String s1 = "Hello";
String s2 = new String("Hello");
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");
}
输出:
s1 != s2
s1 equals s2
说明:s1 s2分别引用了两个对象。显然,两者内容是相同的,因此equal返回true。第一个例子也一样。
我们接下来将详细讨论,为什么在上面两个例子中,s1和s2出现了两种不同的指向对象的情况。
3. 解释
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,那么这种情况的内存是怎么分配的呢,答案是在堆空间和字符串常量池中。每调用一次就会在堆中创建一个新的对象,如果常量池中已经存在"abc",那么就不会额外在常量池中生成引用。因此这句话会产生一个或者两个对象。
而第二种是先在常量池中创建一个对String类的对象引用变量str,然后查找常量池中有没有存放"abc",如果没有,则将"abc"存放并令str指向”abc”,如果已经有”abc”则直接令str指向“abc”。
由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。
具体可以查看此篇String、StringBuider以及StringBuffer的区别和使用场景。
4. String类的intern方法
String s1 = "Hello";
String s2 = new String("Hello");
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");
}
程序输出:
s1 == s2
s1 equals s2
这次加入:s2 = s2.intern(),java.lang.String的intern()方法,"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。但是这也仅仅是JDK1.6以及以前的过时的处理方法,如果想了解更全更清晰的intern()方法,请务必参考我的这篇博文Java技术——你真的了解String类的intern()方法吗。
5. 为什么Java中1000==1000为false而100==100为true?
Integer i1 = 100,i2 = 100;
System.out.println(i1==i2);
Integer i3 = 1000,i4 = 1000;
System.out.println(i3==i4);
查看Integer.java类,会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。
所以例子中i1和i2指向了一个对象。因此100==100为true。
Java面试——从JVM角度比较equals和==的区别的更多相关文章
- Java,哈希码以及equals和==的区别
从开始学习Java,哈希码以及equals和==的区别就一直困扰着我. 要想明白equals和==的区别首先应该了解什么是哈希码,因为在jdk的类库中不管是object实现的equals()方法还是S ...
- Java面试01|JVM相关
1.JVM内存查看与分析,编写内存泄露实例 堆区.栈区.方法区.本机内存都有可能内存溢出.在这里编写堆区内存溢出实例.如下(来自<深入理解Java虚拟机>一书. // -Xms20m -X ...
- Java面试之JVM原理总结
1.什么是JVM? 答:JVM是Java Virual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,他是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟计算机功能来实现 ...
- 【Java面试】JVM如何判断一个对象可以被回收
Hi, 我是Mic. 今天分享一道一线互联网公司必问的面试题. "JVM如何判断一个对象可以被回收" 关于这个问题,来看看普通人和高手的回答. 普通人: 嗯.......... 高 ...
- 【Java面试必备JVM】JVM看这篇就够了
链接–>JVM
- Java面试题:==运算符与equals方法的区别
据说这个面试题目,80%的程序员都会理直气壮的回答错误!! 一: ==运算符 如果比较的是基本数据类型,则直接比较数值是否相等,返回值为"true or false" 如果比较的是 ...
- Java面试之String、StringBuffer和StringBuilder的区别和原理
首先我们先来谈谈String: String 对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象,即修改了 String 的引用. 因为 String 的底层是用数组来 ...
- 【Java面试】Spring中 BeanFactory和FactoryBean的区别
一个工作了六年多的粉丝,胸有成竹的去京东面试. 然后被Spring里面的一个问题卡住,唉,我和他说,6年啦,Spring都没搞明白? 那怎么去让面试官给你通过呢? 这个问题是: Spring中Bean ...
- Java面试系列
如果你的面试简历是如下这样写的,请务必准备回答下面的所有问题. 面试职位:Java高级工程师 专业技能: (1)牢固掌握Java基础知识,如集合.并发.I/O等,并对Java源码有一定的研究. (2) ...
随机推荐
- Java EE学习笔记(三)
Spring AOP 1.Spring AOP简介 1).AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程).它是面向对象编程(OOP)的一种补充 ...
- python入门之lambda表达式、内置函数
lambda 简单的函数就可以用lambda表达式 格式: abc = lambda a1,a2:a1+a2 其中,传参是a1和a2,返回值是a1+a2 内置函数 abs(a) #取绝对值 all(a ...
- Oracle 修改密码(忘记登录密码,用户System)
1.修改计算机环境变量,把oracle服务端路径放在最前面 2.输入cmd 3.输入命令:sysplus /nolog SQL>conn sys/syspwd as sysdba SQL> ...
- Java中IO流文件读取、写入和复制
//构造文件File类 File f=new File(fileName); //判断是否为目录 f.isDirectory(); //获取目录下的文件名 String[] fileName=f.li ...
- 2017 清北学堂 Day 6终极考试报告
预计分数: 100+70+70 = 240 实际假分数 : 40+80+70= 190 in cena(好吧不得不承认这个分数,,,,,,=.=) 实际真分数 : 100+80+100 = 280 ...
- spring @RequestBody 和 @RequestParams 同时使用
@RequestBody 和 @RequestParams 是可以同时使用的. @RequestBody 接受的数据类型是 content-type:"application/json&qu ...
- HDU 4348 I - To the moon 可持续化
队友套的可持续化线段树,徘徊在RE和MLE之间多发过的... 复用结点新的线段树平均要log2N个结点. 其实离线就好,按照时间顺序组织操作然后dfs. #include <iostream&g ...
- 转载:使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
本文将通过简单的UI来说明如何用VFL来实现自动布局.在自动布局的时候避免不了使用代码来加以优化以及根据内容来实现不同的UI. 一:API介绍 NSLayoutConstraint API 1 2 3 ...
- Ace 在Vue中使用方法
var Vue = require('vue/dist/vue.common.js'); document.querySelector('body').append(document.createEl ...
- C04 模块化开发
目录 模块化开发概述 函数概述 如何使用函数 字符串处理函数 模块化开发特点 模块化开发概述 概述 C语言是面向过程的语言,意味着编写C语言程序的时候,我们要像计算机一样思考如何设计程序. 模块化开发 ...