Object方法详解

最近面试有家公司让我回答Object都有哪些方法,平时很少关注,回家补了下脑,它有如下方法:
Object,clone,,equals(Object o)finalizegetClasshashCode,notify,notifyAll,wait, wait(long millis),wait(long millis, int nanos),toString
接下来我就以上加粗的几个方法根据源码注释做一个解释:

  • clone
    该方法被protected修饰,为了对象能够被克隆,类必须实现Cloneable接口,这里涉及到 Shadow 和 Deep 克隆,Deep 克隆时针对非immutable且引用型 的 member,在克隆时须调用该成员的clone,如下:
    Deep Clone:
    public final class ImmutableNestedClass {

        private final String padding;

        public ImmutableNestedClass(String padding) {
            this.padding = padding;
        }

        public final String getPadding() {
            return padding;
        }

    }

    public class NestedClass implements Cloneable{

        private String padding;

        public NestedClass(String padding) {
            this.padding = padding;
        }

        public void setPadding(String padding) {
            this.padding = padding;
        }

        @Override
        public NestedClass clone() {
            NestedClass cloned = null;
            try {
                cloned = (NestedClass) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return cloned;
        }
    }

public class SuperClass {

    String name; // Though name is reference type member, but it is immutable.
    int age;
    NestedClass nestedClass = new NestedClass("padding");

    public SuperClass(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return new StringBuilder().append(name).append(",").append(age).toString();
    }
}

public class SubClass extends SuperClass implements Cloneable {

    private String sex; // Though name is reference type member, but it is immutable.
    private NestedClass nestedInstance;
    private ImmutableNestedClass immutableNestedInstance;

    public SubClass(String sex, String name, int age) {
        super(name, age);
        this.sex = sex;
        this.nestedInstance = new NestedClass("padding");
        this.immutableNestedInstance = new ImmutableNestedClass("padding");
    }

    @Override
    protected SubClass clone() {
        SubClass cloned = null;
        try {
            cloned = (SubClass)super.clone();
            cloned.nestedInstance = nestedInstance.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cloned;
    }

    public NestedClass getNestedInstance() {
        return nestedInstance;
    }

    public ImmutableNestedClass getImmutableNestedInstance() {
        return immutableNestedInstance;
    }

    public String getSex() {
        return sex;
    }

    @Override
    public String toString() {
        return new StringBuilder().append(sex).append(",").append(nestedInstance).append(",").append(super.toString()).toString();
    }

}

Shadow Clone: 其他不变,只改SubClass

public class SubClass extends SuperClass implements Cloneable {

    private String sex; // Though name is reference type member, but it is immutable.
    private NestedClass nestedInstance;
    private ImmutableNestedClass immutableNestedInstance;

    public SubClass(String sex, String name, int age) {
        super(name, age);
        this.sex = sex;
        this.nestedInstance = new NestedClass("padding");
        this.immutableNestedInstance = new ImmutableNestedClass("padding");
    }

    @Override
    protected SubClass clone() {
        SubClass cloned = null;
        try {
            cloned = (SubClass)super.clone();
            // 注释掉以下这行
            // cloned.nestedInstance = nestedInstance.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return cloned;
    }

    public NestedClass getNestedInstance() {
        return nestedInstance;
    }

    public ImmutableNestedClass getImmutableNestedInstance() {
        return immutableNestedInstance;
    }

    public String getSex() {
        return sex;
    }

    @Override
    public String toString() {
        return new StringBuilder().append(sex).append(",").append(nestedInstance).append(",").append(super.toString()).toString();
    }

}

如何验证?用==比较前后实例的非immutable 引用型成员,如果不相等说明深度克隆成功!

待续。。。

  • equals && hashCode
package jc.download.impl;

import android.support.annotation.Nullable;
import android.text.TextUtils;

import jc.download.interfac.Key;
import jc.download.util.Util;

public class UrlKey implements Key {

    String url;
    private String str;

    public UrlKey(String url, @Nullable String str) {
        if (TextUtils.isEmpty(url)) throw new IllegalArgumentException("url can't be null.");
        this.url = url;
        this.str = str;
    }

    @Override
    public boolean equals(Object o){
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) { // much more exactly than using instanceof.
            return false;
        }

        UrlKey that = (UrlKey)o;

        /**
         * If field is primitive compare with '==',  else compare with equals method.
         */
        if (!url.equals(that.url) || (null == str ? that.str != null : !str.equals(that.str))) {
            return false;
        } 
        return true;        
    }

    /**  equal instances must have equal hash codes. */
    @Override
    public int hashCode() {
        // Start with a non-zero constant
        int result = 17;
        result = 31 * result + url.hashCode();
        return result;
    }

    @Override
    public String toString(){
        if (str == null) {
            str = Util.byteArrayToHex(url.getBytes());
        }
        return str;
    }
}

hash code 将作为hash表类数据结构用来计算元素index的重要因子。API说明hashCode最好按照以下规则实现:

Override public int hashCode() {
  // Start with a non-zero constant.
  int result = 17;

  // Include a hash for each field.
  result = 31 * result + (booleanField ? 1 : 0);

  result = 31 * result + byteField;
  result = 31 * result + charField;
  result = 31 * result + shortField;
  result = 31 * result + intField;

  result = 31 * result + (int) (longField ^ (longField >>> 32));

  result = 31 * result + Float.floatToIntBits(floatField);

  long doubleFieldBits = Double.doubleToLongBits(doubleField);
  result = 31 * result + (int) (doubleFieldBits ^ (doubleFieldBits >>> 32));

  result = 31 * result + Arrays.hashCode(arrayField);

  result = 31 * result + referenceField.hashCode();
  result = 31 * result +
      (nullableReferenceField == null ? 0
                                      : nullableReferenceField.hashCode());

  return result;
}
  • finalize

    用途:
    1.回收Native分配的内存
    2.检测程序员的疏漏

按照以下方式来实现:

@Override
protected void finalize() throws Throwable {
    try {
        // TODO. release native resources here.
    }finally {
        super.finalize();
    }
}

不提倡实现finalize的原因是,GC在回收某个对象前会调用finalize方法(如果实现的话),finalize耗时太长,会导致内存得不到及时回收。
比较好的分析:
深入理解ReferenceQueue GC finalize Reference

  • getClass
    用来确认对象是哪个类的实例。
public class SuperClass {
....
}
public class SubClass extends SuperClass {
...
}

SubClass instance = new SubClass();
boolean ret = instance instanceof SubClass; // ret is true
boolean ret = instance instanceof SuperClass; // ret is true
boolean ret = original.getClass() == SubClass.class; // ret is true
boolean ret = original.getClass() == SuperClass.class; // ret is false
  • wait&&notify
boolean set = false;
Object obj = new Object();

//get thread
synchronized (obj) { // synchronized
    while (!set) {
        try {
            obj.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    set = false;
    obj.notify();
}

//set thread
synchronized (obj) {
    while (set) {
        try {
            obj.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    set = true;
    obj.notify();
}

Mark-and-Sweep算法参考

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值