💡源码设计分析
equals
// 原生 Obejct
public boolean equals(Object obj) {
return (this == obj);
}
如果自定义的类没有改写equals
,那么将会执行这个方法其本质是比较两个对象从堆里面引用的地址。
// 原生 String
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- 判断是不是引用同一个地址。
- 判断对象实例是不是 String 兼容类型,比如 String 向上转型为 Object 。
- 将传进来的对象与 String 类型一致,比如 Object 向下转型为 String。
- 比较两个对象 value 长度是否一致
- 比较对象每个字符是否相同实际就是比较数值是否相同,众所周知字符也是用数值来表示的例如
char
。
// 原生 Integer
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
为什么这里没有去判断是否引用同一地址,很简单对于数值来说只要数值相等就行了,没有必要去检查地址,也没有地址怎么一说,这也就是为什么 Integer 实例化时需要传入一个数值才能通过编译。
hashCode
// 原生 Object
public native int hashCode();
native
指明该方法由C/C++语言实现并且编译成DLL由 JVM 调用,反正会生成一个数值。
// 原生 String
public int hashCode() {
int h = hash;// 默认为零
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
- 判断字符长度是否为零
- 通过 time31 算法生成一个数值
s [ 0 ] ∗ 3 1 n − 1 + s [ 1 ] ∗ 3 1 n − 2 + . . . + s [ n − 2 ] n − ( n − 2 ) + s [ n − 1 ] s[0]*31^{n-1}+s[1]*31^{n-2}+...+s[n-2]^{n-(n-2)}+s[n-1] s[0]∗31n−1+s[1]∗31n−2+...+s[n−2]n−(n−2)+s[n−1]
// 原生 Integer
public int hashCode() {
return Integer.hashCode(value);
}
数值本身就是数值没有必要进行转换,直接返回值就可以了,但是为什么不直接使用return value;
反而需要再去调用有参的 hashCode 方法呢?
目前还不知道
toString
// 原生 Object
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 原生 String
public String toString() {
return this;
}
// 原生 Integer
public String toString() {
return toString(value);
}
如果你在自定义类里面不去重写这个方法,默认打印类名和哈希码。
在你实例化对象时,打印的结果就可以由其方法决定。
finaliza
// 原生 Object
protected void finalize() throws Throwable { }
// 原生 String 无
// 原生 Integer 无
只能被子类调用且在被 system.gc()
回收之前做最后的挣扎。
如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀