Effective Java(6~10)
程序员文章站
2022-07-12 17:50:48
...
第六条 消除过期的对象引用
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
第七条 避免使用终结方法
第八条 覆盖equals方法时请遵守通用约定
使用==
操作符检查"参数是否为这个对象的引用" 如果是,则返回true. 这只不过是一种性能优化,如果比较操作有可能很昂贵,就值得这么做 (平时没有用过,怎么样的比较操作算是昂贵的呢?)使用instanceof
操作符检查"参数是否为正确的类型" 如果不是,则返回false。把参数装换成正确的类型。(这个比较好理解,instanceof检测后,一般都会强转成所需类型)对于该类中的每个关键域,检查参数中的域是否与对象中对应的域相配。(比如学生类有学号,班级,姓名这些重要的属性,我们都需要去比对)
public class Student {
public String name;
public String className;
@Override
public boolean equals(Object obj) {
//对于一个null的对象 我们总是返回false
if (null == obj) {
return false;
}
// 利用instanceof检查类型后,强转
if (obj instanceof Student){
Student other = (Student) obj;
//再对关键的属性做比较 得出结论
if (name.equals(other.name) && className.equals(other.className)) {
return true;
}
}
return false;
}
}
第九条 覆盖equals时总要覆盖hashCode
public class Person {
int age;
String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// @Override
// public int hashCode() {
// final int prime = 31;
// int result = 1;
// result = prime * result + age;
// result = prime * result + ((name == null) ? 0 : name.hashCode());
// return result;
// }
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
}
public class EqualTest {
public static void main(String[] args) {
Person p1 = new Person(10, "张三");
Person p2 = new Person(10, "张三");
System.out.println(
"p1.equals(p2)=" + p1.equals(p2) + ", p1.hashcode=" + p1.hashCode() + ", p2.hashcode=" + p2.hashCode());
}
}
实例化两个相同的对象,如果 不重写hashCode,则两个对象即使属性值相同,equals结果为true,但hashCode是不同的。map会认为这是两个值相同的对象。
如果重写hashCode,这连个对象的hashCode值相同,map会认为这是系统一个对象。
第十条 始终要覆盖toString
便于理解返回值中的信息