Chapter3_操作符_关系操作符
java中的关系操作符有等于“=”,不等于“!=”,大于“>”,小于“<”,大于等于“≥”,小于等于“≤”等。这些都不再赘述了,有一个有意思的点是关于等价性的讨论。
在java中测试两个对象或者基本数据类型经常会使用到“=”和.equals静态方法,这两者的机制通常会让人感到迷惑。
下面贴出测试代码:
1 class dog{
2 String name;
3 String says;
int age;
}
public class Test {
public static void main(String[] args){
dog d1 = new dog();
dog d2 = new dog();
d1.says = "ruff!";
d1.name = "spot";
d1.age = 3;
d2.says = "ruff!";
d2.name = "spot";
d2.age = 3;
//比较引用
System.out.println(d1 == d2);
System.out.println(d1.equals(d2));
//比较字符串
System.out.println(d1.name == d2.name);
System.out.println(d1.name.equals(d2.name));
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
//比较基本类型
Integer a1 = new Integer(1);
Integer a2 = new Integer(1);
System.out.println(d1.age == d2.age);
System.out.println(a1 == a2);
System.out.println(a1.equals(a2));
//error:System.out.println(d1.age.equals(d2.age));
}
}
false
false
true
true
false
true
true
false
true
这段代码首先创建了一个类名为dog,它具有三个域:says(string),name(string),age(int)。在测试的主方法中,首先用new关键字创建出了两个对象的引用d1,d2,这两个用new创建的引用是存储在堆中的。这两个对象引用指向的对象所包含的域,内容上都是完全一样的。首先是对引用的比较,很显然由于是在堆中创建的,d1和d2所指向的是不同的对象,指向堆中不同的内存区域,而由于==比较的是对对象的引用,所以很显然第一个比较得出的结果是false,在这一点上(对对象引用的比较),equals静态方法的机制似乎和它一样,也是比较引用指向的地址而不是对象域中的内容。
接下来看对字符串的比较,这里直接对d1和d2两个对象的string域进行比较,很让人疑惑的是得出的结果居然是两个true,而下面用两个new出来的对象进行比较的结果是false和true。这里的区别就在于这个关键字new上。java的内存分配机制中,new出来的对象都是被存储在堆中的,而其他一些基本类型的数据则是分配在栈中,在之前的d1.name="spot"和d2.name="spot"中,实际上进行的操作是,在栈中开辟了一块内存来存储这个"spot"字符串,然后d1和d2的name域中的指针都指向这一块区域,这样就很容易理解此时比较出来的结果了。而下面new出来的两个字符串"abc"都是存储在堆中,它们分配到的是不同的内存区域,因此此时用“==”比较的结果自然是false,因为两者的指针不是指向的同一块区域,但对于字符串,equals方法的行为就是按字符比较,结果自然是true。
最后是对基本数据类型的比较,有了之前的介绍就好理解多了。a1和a2虽然数值相同,但在堆中的内存区域不同,所以比较结果是false,反之,在给对象的域赋值时,由于是在栈中创建的,所以指向的区域是相同的。而对于四种基本数据类型,此时equals的行为仍旧是比较对象的数值。
总结如下:
(1)java内存分配的规则是,对于用new关键词创建出的对象,都存储在堆中。而对于没有使用new关键词创建的基本的数据(四种基本数据类型,字符串),和对象的引用,存储在栈中。
(2)比较对对象的引用时,“==”和equals方法都是比较对对象的引用。如果需要有不同的表现方法,需要对类的equals方法进行重写(重写object的equals)。
(3)比较字符串和四种基本数据类型时,“==”仍然比较对象的引用,而equals比较字符串的内容或者数据的内容。
Chapter3_操作符_关系操作符的更多相关文章
- Chapter3_操作符_逻辑操作符
逻辑操作符与(&&)或(||)非(^)能够对布尔类型的数据类型进行操作,并且生成布尔值,和关系操作符的产生的数据类型是一样的.需要注意的不多,有以下几点: (1)在需要使用string ...
- Chapter3_操作符_其他操作符
对java中其他操作符及一些注意事项的总结 (1)按位操作符 按位操作符操作基本整数类型中的单个二进制位,有与(&),或(|),非(~).按位操作符还可以和等号(=)联合使用,如~=,& ...
- Chapter3_操作符_算术操作符
java中的算术操作符与其它语言并无太大区别,常用到的是以下这些: (1)加号(+),减号(-),除号(\),乘号(*),取模操作符(%),其中除号需要特别注意的是,会自动截取掉小数点后面的部分,而不 ...
- Chapter3_操作符_别名机制
Java中的别名机制实际体现的是对于“=”这一类赋值操作符的使用规则和内涵.“=”的实际内涵是指将右边的变量的值(对于基本数据类型而言)或者某一个对象的引用(对于某个具体对象而言)复制到左边的变量名所 ...
- Chapter3_操作符_直接常量和指数计数法
(1)直接常量 在程序中使用直接常量,相当于指导编译器,告诉它要生成什么样的类型,这样就不会产生模棱两可的情况.比如flaot a = 1f等,后缀表示告诉编译器想生成的类型.常用的后缀有l/L(lo ...
- Chapter3_操作符_方法调用中的别名问题
接下来展示方法调用中的别名问题,方法调用中的别名问题指的是,将一个对对象的引用传递给某一个方法时,方法操作的是这一个特定的引用而不是这个引用的拷贝. class Person{ float heigh ...
- js中等性操作符(==)、关系操作符(<,>)和布尔操作符(!)比较规则
最近一直在笔试面试,经常碰到例如 123=='123'.'abc'==true等问题,其中有答对的,也有答错的,主要原因还是对ECMAScript的规范没有理解清楚,很多题目没有具体分析所导致.现查阅 ...
- JavaScript操作符(关系操作符、相等操作符和条件操作符)
关系操作符用于对两个值进行比较,返回一个布尔值.关系操作符包括大于(>),小于(<),大于等于(>=),小于等于(<=).当关系操作符用于非数值时,也要先进行数值的转换.如 v ...
- Java知识系统回顾整理01基础04操作符02关系操作符
一.关系操作符 关系操作符:比较两个变量之间的关系 > 大于 >= 大于或等于 < 小于 <= 小于或等于 == 是否相等 != 是否不等 public class Hell ...
随机推荐
- Linux下安装MySQL----来自简书(挺好的)
来自简书的: https://www.jianshu.com/p/f4a98a905011 注: 1. 下载方式: 可以使用命令下载: wget http://downloads.mysql.com/ ...
- ARM 版本
M microcontroller 单片机 STM32 M0 M0+ M3 M4 M7低功耗 A applicatioin 应用 ...
- Django文件存储(一)默认存储系统
Django默认使用的文件存储系统'django.core.files.storage.FileSystemStorage'是一个本地存储系统,由settings中的DEFAULT_FILE_STOR ...
- python3 re.compile中含有变量
id = '7F' reg = re.compile(id + '[^\dA-F]?\d') line = ‘122s 7f 3' match = reg.search(line) 在程序中有时候会遇 ...
- python大法好——Python 面向对象
Python 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的. 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法 ...
- java性能优化总结
本人在java中积累了一些性能优化相关的经验,现在总结如下: 批量处理服务性能优化 RTB服务性能优化 BasicData线上问题解决,疯狂FullGC的问题 BasicData线上部分服务器cpu使 ...
- leetcode20
public class Solution { Stack<char> S = new Stack<char>(); public bool IsValid(string s) ...
- 第一篇、Python初识
1.Python文件后缀是否可以任意? 单独执行的时候没关系,但当文件需要导入(即导入模块)的时候,如果不是py后缀的,会出错. 2.执行方法 1) python +文件路径 python + fil ...
- @ResponseBody 与 response.getWriter.write
@responseBody注解的使用 1. @responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通 ...
- 记号一下selenium+Firefox自动下载的参数
参考: https://blog.csdn.net/wxstar8/article/details/80782556 https://blog.csdn.net/xiaoguanyusb/articl ...