对于引用类型来说, == 判断的是两边的引用是否相等,也就是判断两个对象是否指向了同一块内存区域。
private void equals(){ System.out.println(person1.getName().equals(person2.getName())); }equals 是 Java 中所有对象的父类,即 Object 类定义的一个方法。它只能比较对象,它表示的是引用双方的值是否相等。所以记住,并不是说 == 比较的就是引用是否相等,equals 比较的就是值,这需要区分来说的。
equals 用作对象之间的比较具有如下特性
自反性:对于任何非空引用 x 来说,x.equals(x) 应该返回 true。
对称性:对于任何非空引用 x 和 y 来说,若x.equals(y)为 true,则y.equals(x)也为 true。
传递性:对于任何非空引用的值来说,有三个值,x、y 和 z,如果x.equals(y) 返回true,y.equals(z) 返回true,那么x.equals(z) 也应该返回true。
一致性:对于任何非空引用 x 和 y 来说,如果 x.equals(y) 相等的话,那么它们必须始终相等。
非空性:对于任何非空引用的值 x 来说,x.equals(null) 必须返回 false。
Java 中的基本数据类型有哪些,各自占用多少字节在 Java 中,数据类型只有四类八种
整数型:byte、short、int、long
byte 也就是字节,1 byte = 8 bits,byte 的默认值是 0 ;
short 占用两个字节,也就是 16 位,1 short = 16 bits,它的默认值也是 0 ;
int 占用四个字节,也就是 32 位,1 int = 32 bits,默认值是 0 ;
long 占用八个字节,也就是 64 位,1 long = 64 bits,默认值是 0L;
所以整数型的占用字节大小空间为 long > int > short > byte
浮点型
浮点型有两种数据类型:float 和 double
float 是单精度浮点型,占用 4 位,1 float = 32 bits,默认值是 0.0f;
double 是双精度浮点型,占用 8 位,1 double = 64 bits,默认值是 0.0d;
字符型
字符型就是 char,char 类型是一个单一的 16 位 Unicode 字符,最小值是 \u0000 (也就是 0 ),最大值是 \uffff (即为 65535),char 数据类型可以存储任何字符,例如 char a = 'A'。
布尔型
布尔型指的就是 boolean,boolean 只有两种值,true 或者是 false,只表示 1 位,默认值是 false。
以上 x 位都指的是在内存中的占用。
String 中的 equals 是如何重写的String 代表的是 Java 中的字符串,String 类比较特殊,它整个类都是被 final 修饰的,也就是说,String 不能被任何类继承,任何 修改 String 字符串的方法都是创建了一个新的字符串。
equals 方法是 Object 类定义的方法,Object 是所有类的父类,当然也包括 String,String 重写了 equals 方法,下面我们来看看是怎么重写的
首先会判断要比较的两个字符串它们的引用是否相等。如果引用相等的话,直接返回 true ,不相等的话继续下面的判断
然后再判断被比较的对象是否是 String 的实例,如果不是的话直接返回 false,如果是的话,再比较两个字符串的长度是否相等,如果长度不想等的话也就没有比较的必要了;长度如果相同,会比较字符串中的每个 字符 是否相等,一旦有一个字符不相等,就会直接返回 false。
下面是它的流程图
这里再提示一下,你可能有疑惑什么时候是
if (this == anObject) { return true; }这个判断语句如何才能返回 true?因为都是字符串啊,字符串比较的不都是堆空间吗,猛然一看发现好像永远也不会走,但是你忘记了 String.intern() 方法,它表示的概念在不同的 JDK 版本有不同的区分
在 JDK1.7 及以后调用 intern 方法是判断运行时常量池中是否有指定的字符串,如果没有的话,就把字符串添加到常量池中,并返回常量池中的对象。
验证过程如下
private void StringOverrideEquals(){ String s1 = "aaa"; String s2 = "aa" + new String("a"); String s3 = new String("aaa"); System.out.println(s1.intern().equals(s1)); System.out.println(s1.intern().equals(s2)); System.out.println(s3.intern().equals(s1)); }
首先 s1.intern.equals(s1) 这个无论如何都返回 true,因为 s1 字符串创建出来就已经在常量池中存在了。
然后第二条语句返回 false,因为 s1 返回的是常量池中的对象,而 s2 返回的是堆中的对象
第三条语句 s3.intern.equals(s1),返回 true ,因为 s3 对象虽然在堆中创建了一个对象,但是 s3 中的 "aaa" 返回的是常量池中的对象。