java object类中的clone_java中的Object类和其clone()

1.Object是所有类的父类,任何类都默认继承Object,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因此省略了

extends Object关键字。

2.Object类中主要有以下方法:

toString()  getClass()  equals()  clone()  finalize()  notify()  notifyAll()  wait()

其中toString(),getClass(),equals()是其中最重要的方法。getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写。

3.clone()方法

public classObject {protected native Object clone() throwsCloneNotSupportedException;

}

(1) clone()存在的原因是Java里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递。可以在类中复写clone方法以实现深拷贝。

(2) Object类的 clone() 方法是一个native方法,native方法的效率一般来说都是远高于Java中的非native方法。这也解释了为什么要用Object中clone()

方法而不是先new一个类,然后把原始对象中的信息复制到新对象中。

(3) 必须要重写clone()方法以达到在类外使用的目的。

(4) Object.clone()方法返回一个Object对象, 必须进行强制类型转换才能得到我们需要的类型。

在派生类中实现Cloneable接口。奇怪的发现Cloneable竟然是空的,它仅仅是一个标志,而且这个标志也仅仅是针对 Object类中 clone()方法的,如果 clone 类没有实现

Cloneable 接口,并调用了 Object 的 clone() 方法(也就是调用了 super.Clone() 方法),那么Object 的 clone() 方法就会抛出

CloneNotSupportedException 异常。

clone使用demo1:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

class Person implements Cloneable { //clone()是Object类中的protected成员方法。继承Cloneable只是为了运行时不要报异常。

private intage ;privateString name;public Person(intage, String name) {this.age =age;this.name =name;

}publicPerson() {}public intgetAge() {returnage;

}publicString getName() {returnname;

}/** 这里必须要复写Object类的clone()方法,原因:

* Object类中的clone()方法是protected权限,只能在本包中或者在其它包的子类中访问(注意是子类中)

* 这里重写一下,虽然还是protected的,但是可以在本包中访问了。*/@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

}public classTest {public static voidmain(String args[]) {

Person p= new Person(23, "zhang");

Person p1= null;try{

p1= (Person) p.clone(); //非子类中访问clone()方法

} catch(CloneNotSupportedException e) {

e.printStackTrace();

}if (p1 != null) {

System.out.println(p);//若引用的是同一个类,打印的hash值是一样的,clone的是不同的

System.out.println(p1);

}

}

}

View Code

如果想要拷贝一个对象,这个对象必须要实现Cloneable接口,实现clone方法。

clone使用demo2:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classCloneTest {static class Body implementsCloneable {/**/

public Head head;

public Body() {}

public Body(Head head) { this.head = head; }

@Override

protected Object clone() throws CloneNotSupportedException {

Body newBody = (Body)super.clone();

newBody.head = (Head)head.clone(); //

return newBody;

}

}

static class Head implements Cloneable {

public Face face;

public Head() {}

public Head(Face face){ this.face = face; }

@Override

protected Object clone() throws CloneNotSupportedException {

Head newHead = (Head)super.clone();

newHead.face = (Face)face.clone(); // face.clone();相对于Face类来说在Face类外部,若Face类没有重写这个接口将报错

return newHead;

}

}

static class Face implements Cloneable {

@Override

protected Object clone() throws CloneNotSupportedException {

return super.clone();

}

}

public static void main(String[] args) throws CloneNotSupportedException {

Body body = new Body(new Head(new Face()));

Body body1 = (Body) body.clone();

System.out.println("body == body1 : " + (body == body1) );

System.out.println("body.head == body1.head : " + (body.head == body1.head));

System.out.println("body.head.face == body1.head.face : " + (body.head.face == body1.head.face));

}

}

View Code

若Face类不实现Cloneable接口,Head类中也不调用face.clone(),那么成员对象face传的还是引用!这就是一种不彻底的深拷贝。

结论:如果想要深拷贝一个对象,这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象成员变量中引用的其他对象也要clone一份,这就要求这个被成员对象引用的对象必须也要实现Cloneable接口并且重写clone方法。

4.toString()方法

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

}

一般子类重写这个方法以便打印自己想到的内容。

5.getClass()方法

public final native Class> getClass();

返回此Object运行时类类型,final修饰不可重写,一般和getName()联合使用,如getName().getClass().

6.finalize()方法

protected void finalize() throws Throwable {}

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

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

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

b.垃圾回收并不等于“析构”。

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

7.equals()方法

public booleanequals(Object obj) {return (this ==obj);

}

直接判断的是引用,若想判断内容是否相同,需要重写此方法。

8.hashCode()方法

public native int hashCode();

返回该对象的哈希值,该方法用于哈希查找.

9.wait()方法

public final native void wait() throwsInterruptedException;public final native void wait(long timeout) throws InterruptedException; //超时时间timeout ms

wait()方法一直等待,直到获得锁或者被中断。wait(timeout)如果在规定时间内没有获得锁就返回。

调用该方法后当前线程进入睡眠状态,直到以下事件发生。

a.其他线程调用了该对象的notify方法。

b.其他线程调用了该对象的notifyAll方法。

c.其他线程调用了interrupt中断该线程。

d.时间间隔到了。

注意:只有获取锁后wait()方法才起作用,没有获取锁调用wiat()方法无效。调用wait()方法后会释放线程锁,等待结束后重新获取锁继续执行。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

classA {public synchronized void printThreadInfo() throwsInterruptedException

{int i = 0;while (i++ < 5) {this.wait(1000);

System.out.println("Still need wait resourse");

}

}

}public classTest {public static voidmain(String args[]) {

A a= newA();try{

a.printThreadInfo();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classWaitNotifyTest {public static voidmain(String[] args) {final Object lock = new Object(); //局部变量lock在内部类中访问了,需要加上final修饰

new Thread(newRunnable() {

@Overridepublic voidrun() {

System.out.println("线程A等待获取lock锁");synchronized(lock) {try{

System.out.println("线程A获取了lock锁");

Thread.sleep(1000);

System.out.println("线程A将要运行lock.wait()方法进行等待");

lock.wait();

System.out.println("线程A等待结束");

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();new Thread(newRunnable() {

@Overridepublic voidrun() {

System.out.println("线程B等待获取lock锁");synchronized(lock) {

System.out.println("线程B获取了lock锁");try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("线程B将要运行lock.notify()方法进行通知");

lock.notify();

}

}

}).start();

}

}

View Code

JVM的一些函数使用了JNI

static JNINativeMethod methods[] ={

{"hashCode", "()I", (void *)&JVM_IHashCode},

{"wait", "(J)V", (void *)&JVM_MonitorWait},

{"notify", "()V", (void *)&JVM_MonitorNotify},

{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},

{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},

};

参考:https://blog.csdn.net/qq_38293564/article/details/80432875

10.notify()方法

public final native void notify();

该方法唤醒在该对象上等待的某个线程。

11.notifyAll()方法

public final native void notifyAll();

该方法唤醒在该对象上等待的所有线程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值