java 提高篇_Java提高篇(一)——Object详解

大家都知道Object是所有类的父类,任何类都默认继承Object。

理论上Object类是所有类的父类,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因此省略了extends Object关键字。

Object主要有以下方法

返回类型

方法名

说明

protected Object

clone()

创建并返回此对象的一个副本。

boolean

equals(Object obj)

指示其他某个对象是否与此对象“相等”。

protected void

finalize()

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

Class>

getClass()

返回此 Object 的运行时类。

int

hashCode()

返回该对象的哈希码值。

void

notify()

唤醒在此对象监视器上等待的单个线程。

void

notifyAll()

唤醒在此对象监视器上等待的所有线程。

String

toString()

返回该对象的字符串表示。

void

wait()

在其他线程调用此对象的notify()方法或notifyAll()方法前导致当前线程等待

void

wait(long timeout)

在其他线程调用此对象的notify()方法或notifyAll()方法,或者超过指定的时间量前,导致当前线程等待

void

wait(long timeout, int nanos)

在其他线程调用此对象的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。

注意:

Object类中的getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写。

一、clone()方法

保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。

源码如下

protected Object clone() throws CloneNotSupportedException {

if (!(this instanceof Cloneable)) {

throw new CloneNotSupportedException("Class " + getClass().getName() +

" doesn't implement Cloneable");

}

return internalClone();

}

主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里讲参数改变,这是就需要在类中复写clone方法(实现深复制)。

创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。

clone与copy的区别

假设现在有一个People对象,People people = new People(“ZhangSan”,18)。

通常我们会有这样的赋值People people2 = people,这个时候只是简单了copy了一下reference,people2 和people2都指向内存中同一个object,这样people或者people2的一个操作都可能影响到对方。打个比方,如果我们通过people .raiseSalary()方法改变了salary域的值,那么people 2通过etSalary()方法得到的就是修改之后的salary域的值,显然这不是我们愿意看到的。

我们希望得到tobby的一个精确拷贝,同时两者互不影响,这时候我们就可以使用Clone来满足我们的需求。People people2=people .clone(),这时会生成一个新的People 对象,并且和people 具有相同的属性值和方法。

二、equals()方法

源码如下

public boolean equals(Object obj) {

return (this == obj);

}

Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象。

所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的hi同一块内存对象,则返回true,如果this和obj指向的不是同一块内存,则返回false。

注意:即便是内容完全相等的两块不同的内存对象,也返回false。

如果是同一块内存,则object中的equals方法返回true,如果是不同的内存,则返回false

大家都知道

1、"abc".equals("acd")比较的是内容是否相等

2、 "abc" == "acd"比较的是内存地址是否相等

1中比较的是内容相等,而源码中的equal(Object obj)比较的明明是内存地址是否相等啊。什么状况???,我们这里看看String的源码

public boolean equals(Object anObject) {

if (this == anObject) {

return true;

}

if (anObject instanceof String) {

String anotherString = (String) anObject;

int n = length();

if (n == anotherString.length()) {

int i = 0;

while (n-- != 0) {

if (charAt(i) != anotherString.charAt(i))

return false;

i++;

}

return true;

}

}

return false;

}

很明显,String类对equals(Object obj)方法进行了重写,比较的是内容。

注意很多类都已重写equals(Object obj)方法。

三finalize()方法

protected void finalize() throws Throwable { }

该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。

Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

关于垃圾回收,有三点需要记住:

- 1、对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。

- 2、垃圾回收并不等于“析构”。

- 3、垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。

finalize()的用途:

无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。

不过这种情况一般发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。

四getClass()方法

public final Class> getClass() {

return shadow$_klass_;

}

返回次Object的运行时类类型。

不可重写,要调用的话,一般和getName()联合使用,如getClass().getName();

五、hashCode()方法

public int hashCode() {

return identityHashCode(this);

}

// Android-changed: add a local helper for identityHashCode.

// Package-private to be used by j.l.System. We do the implementation here

// to avoid Object.hashCode doing a clinit check on j.l.System, and also

// to avoid leaking shadow$_monitor_ outside of this class.

/* package-private */ static int identityHashCode(Object obj) {

int lockWord = obj.shadow$_monitor_;

final int lockWordStateMask = 0xC0000000; // Top 2 bits.

final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).

final int lockWordHashMask = 0x0FFFFFFF; // Low 28 bits.

if ((lockWord & lockWordStateMask) == lockWordStateHash) {

return lockWord & lockWordHashMask;

}

return identityHashCodeNative(obj);

}

@FastNative

private static native int identityHashCodeNative(Object obj);

返回该对象的哈希码值

该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。

一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。

如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。

六、toString()方法

Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。

public String toString() {

return getClass().getName() + "@" + Integer.toHexString(hashCode());

}

该方法用得比较多,一般子类都有覆盖。

代码实例

public class TestOne {

public static void main(String[] args) {

// TODO Auto-generated method stub

Object obj = new Object();

System.out.println(obj.toString());

}

}

输出结果:java.lang.Object@15db9742

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值