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_操作符_关系操作符的更多相关文章

  1. Chapter3_操作符_逻辑操作符

    逻辑操作符与(&&)或(||)非(^)能够对布尔类型的数据类型进行操作,并且生成布尔值,和关系操作符的产生的数据类型是一样的.需要注意的不多,有以下几点: (1)在需要使用string ...

  2. Chapter3_操作符_其他操作符

    对java中其他操作符及一些注意事项的总结 (1)按位操作符 按位操作符操作基本整数类型中的单个二进制位,有与(&),或(|),非(~).按位操作符还可以和等号(=)联合使用,如~=,& ...

  3. Chapter3_操作符_算术操作符

    java中的算术操作符与其它语言并无太大区别,常用到的是以下这些: (1)加号(+),减号(-),除号(\),乘号(*),取模操作符(%),其中除号需要特别注意的是,会自动截取掉小数点后面的部分,而不 ...

  4. Chapter3_操作符_别名机制

    Java中的别名机制实际体现的是对于“=”这一类赋值操作符的使用规则和内涵.“=”的实际内涵是指将右边的变量的值(对于基本数据类型而言)或者某一个对象的引用(对于某个具体对象而言)复制到左边的变量名所 ...

  5. Chapter3_操作符_直接常量和指数计数法

    (1)直接常量 在程序中使用直接常量,相当于指导编译器,告诉它要生成什么样的类型,这样就不会产生模棱两可的情况.比如flaot a = 1f等,后缀表示告诉编译器想生成的类型.常用的后缀有l/L(lo ...

  6. Chapter3_操作符_方法调用中的别名问题

    接下来展示方法调用中的别名问题,方法调用中的别名问题指的是,将一个对对象的引用传递给某一个方法时,方法操作的是这一个特定的引用而不是这个引用的拷贝. class Person{ float heigh ...

  7. js中等性操作符(==)、关系操作符(<,>)和布尔操作符(!)比较规则

    最近一直在笔试面试,经常碰到例如 123=='123'.'abc'==true等问题,其中有答对的,也有答错的,主要原因还是对ECMAScript的规范没有理解清楚,很多题目没有具体分析所导致.现查阅 ...

  8. JavaScript操作符(关系操作符、相等操作符和条件操作符)

    关系操作符用于对两个值进行比较,返回一个布尔值.关系操作符包括大于(>),小于(<),大于等于(>=),小于等于(<=).当关系操作符用于非数值时,也要先进行数值的转换.如 v ...

  9. Java知识系统回顾整理01基础04操作符02关系操作符

    一.关系操作符 关系操作符:比较两个变量之间的关系  > 大于 >= 大于或等于 < 小于 <= 小于或等于 == 是否相等 != 是否不等 public class Hell ...

随机推荐

  1. 廖雪峰Java7处理日期和时间-4最佳实践-最佳实践

    jdk提供了2套新旧的API来处理日期和时间. java.util * Date * Calendar java.time(JDK>=1.8) * Localdate * LocalTime * ...

  2. Zookeeper集群节点数量为什么要是奇数个?

    无论是公司的生产环境,还是自己搭建的测试环境,Zookeeper集群的节点个数都是奇数个.至于为什么要是奇数个,以前只是模糊的知道是为了满足选举需要,并不知道详细的原因.最近重点学习zookeeper ...

  3. 解决Error:Could not determine the class-path for interface com.android.builder.model.AndroidProject.

    见https://blog.csdn.net/qq_21397217/article/details/65630730博客

  4. DataBaseDaoAbstract

    import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.PreparedStatement; imp ...

  5. disabled和readonly区别

    disabled和readonly这两个属性有一些共同之处,比如都设为true,则form属性将不能被编辑,往往在写js代码的时候容易混合使用这两个属性,其实他们之间是有一定区别的: 如果一个输入项的 ...

  6. JVM内容梳理

  7. 多线程利器-队列(queue)

    #队列有3中模式,先进先出,先进后出,优先级 1:先进先出import queue q = queue.Queue() #默认是先进先出q.put(12)q.put('jack')q.put({'na ...

  8. js 模拟css3 动画1

    <html> <head> <title> javaScript缓动入门 </title> </head> <body> < ...

  9. 如何将R中的data frame对象的数据导入到DB

    在使用ARIMA模型来预测我们的销量的时候,如果保存预测版本进DB,以供后续分析呢 1. 在定义变量阶段我们定义了dfResult      <- data.frame() 这是一个data f ...

  10. 百度分享不支持Https的解决方案--本地化

    站点自从开启 https 之后 ,百度分享就不能用了!但是又寻找不到类似百度分享的替代品.. 怎么办呢?要如何解决 百度分享不支持https的问题呢, 跟着博主动动手,让你百度分享仍然能在https下 ...