欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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会认为这是两个值相同的对象。

Effective Java(6~10)

如果重写hashCode,这连个对象的hashCode值相同,map会认为这是系统一个对象。

Effective Java(6~10) 

第十条 始终要覆盖toString

便于理解返回值中的信息