首页 > 编程语言 >Java之Object类

Java之Object类

时间:2023-05-06 16:45:21浏览次数:43  
标签:Java 对象 Clone Object equals 方法 wait

1、Object类概述   Object类存储在java.lang包中,是所有java类(Object类除外)的终极父类(可以在代码中明确地写出声明要“继承Object类”,没有任何错误)。当然,数组也继承了Object类。但是,接口是不继承Object类的。接口只是是抽象类的延伸,可以将它看做是纯粹的抽象类,接口中的所有方法,都没有方法体。Object类中声明了以下函数:

protected Object clone()
boolean equals(Object obj)
protected void finalize()
Class< > getClass()
int hashCode()
void notify()
void notifyAll()
String toString()
void wait()
void wait(long timeout)
void wait(long timeout, int nanos)

java的任何类都继承了这些函数,并且可以覆盖不被final修饰的函数。例如,没有final修饰的toString()函数可以被覆盖,但是final wait()函数就不行。 Object类中的getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写。

  2、clone()方法 实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。   主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里讲参数改变,这是就需要在类中复写clone方法(实现深复制)。 protected native Object clone() throws CloneNotSupportedException; 创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。     2.1、clone与copy的区别   假设现在有一个Employee对象,Employee tobby =new Employee(“CMTobby”,5000),通常我们会有这样的赋值Employee cindyelf=tobby,这个时候只是简单了copy了一下reference,cindyelf和tobby都指向内存中同一个object,这样cindyelf或者tobby的一个操作都可能影响到对方。打个比方,如果我们通过cindyelf.raiseSalary()方法改变了salary域的值,那么tobby通过getSalary()方法得到的就是修改之后的salary域的值,显然这不是我们愿意看到的。我们希望得到tobby的一个精确拷贝,同时两者互不影响,这时候 我们就可以使用Clone来满足我们的需求。Employee cindy=tobby.clone(),这时会生成一个新的Employee对象,并且和tobby具有相同的属性值和方法。   2.2、Shallow Clone浅拷贝与Deep Clone深拷贝   Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。这样,问题就来了。   以Employee为例,它里面有一个域hireDay不是基本数据类型的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:    这个时候我们就需要进行deep Clone了,对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。我们可以重新定义Clone方法,对hireDay做特殊处理,如下代码所示:  
class Employee implements Cloneable  {  
        public Object clone() throws CloneNotSupportedException  {  
             Employee cloned = (Employee) super.clone();  
             cloned.hireDay = (Date) hireDay.clone()  
             return cloned;  
        }  
}
2.3、clone方法的保护机制   在Object中Clone()是被声明为protected的,这样做是有一定的道理的,以Employee类为例,通过声明为protected,就可以保证只有Employee类里面才能“克隆”Employee对象   2.4、clone方法的使用      Clone()方法的使用比较简单,注意如下几点即可:   1、什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable 2、调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException   3、toString()方法 Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。该方法用得比较多,一般子类都有覆盖。
public String toString(){
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
 
4、getClass()方法 public final native class<?> getClass(); 返回次Object的运行时类类型。不可重写,要调用的话,一般和getName()联合使用,如getClass().getName();   5、finalize()方法 protected void finalize() throws Throwable(){}   该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。   Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。   关于垃圾回收,有三点需要记住: 1、对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。 2、垃圾回收并不等于“析构”。 3、垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。   finalize()的用途:无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过这种情况一般发生在使用“本地方法”的情况下。   6、equals()方法   Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象,所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的hi同一块内存对象,则返回true,如果this和obj指向的不是同一块内存,则返回false。 public boolean equals(Object obj) {     return (this == obj); } 注意:即便是内容完全相等的两块不同的内存对象,也返回false。如果是同一块内存,则object中的equals方法返回true,如果是不同的内存,则返回false如果希望不同内存但相同内容的两个对象equals时返回true,则我们需要重写父类的equal方法,String类已经重写了object中的equals方法(这样就是比较内容是否相等了)   7、hashCode()方法 public native int hashCode(){..} 返回该对象的哈希码值,该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。一般必须满足obj1.equals(obj2)==true。可以推出obj1.hashCode()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。   8、wait()方法
public final void wait() throws InterruptedException{
    wait(0);
}
public final void wait(long timeout) throws InterruptedException{...}
public final void wait(long timeout, int nanos) throws InterruptedException{
    if(timeout <0){
        throw new IllegalArgumentException("timeout value is negative");
    }
    if(nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException("nanosecond timeout value out is range");
    }
    if(nanos > 0){
        timeout++;
    }
    wait(timeout);   
}
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。   调用该方法后当前线程进入睡眠状态,直到以下事件发生: (1)其他线程调用了该对象的notify方法。 (2)其他线程调用了该对象的notifyAll方法。 (3)其他线程调用了interrupt中断该线程。 (4)时间间隔到了。 此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。   9、notify()方法 public final native void notify(){...} 该方法唤醒在该对象上等待的某个线程。   10、notifyAll方法 public final native void notifyAll(){...} 该方法唤醒在该对象上等待的所有线程。  

标签:Java,对象,Clone,Object,equals,方法,wait
From: https://www.cnblogs.com/liujiarui/p/17377875.html

相关文章

  • Java文件流(IO流)
    在编程中,数据存储是重中之重,在之前的学习中所有程序中的数据都是临时存放在内存中的,不能做到有效存储和长久保存,而本次的文件流就暂时解决了数据不能长久存储的问题(虽然后面会学习数据库存储,但文件流存储也很常用)。须知无论是读取文件还是写入文件等操作,在计算机中都是以流的形式进......
  • javaScript 常用去除 ‘console
    javaScript常用去除‘console.log’办法手动注释掉console.log语句:可以手动在代码中注释掉所有console.log语句,但是这种方法比较繁琐,并且需要手动维护,不太适合大型项目。使用Babel插件去除console.log:Babel是一个JavaScript编译器,它可以将ES6+的代码转换成......
  • java类序列化和反序列化
    参考:https://zhuanlan.zhihu.com/p/144535172?utm_id=0https://blog.csdn.net/qq_42617455/article/details/1096223901、问题解答(1)序列化和反序列化都需要哪些操作对象要实现java.io.Serializable接口增加序列化ID(privatestaticfinallongserialVersionUID)转化成便于传......
  • java内存监控工具及命令
    关键字:内存监控工具及命令一篇非常好的内存监控知识,分享给爱学习的亲们.....jinfo:可以输出并修改运行时的java进程的opts。jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。jstat:一个极强的监视VM......
  • TypeError: 'numpy.float64' object cannot be interpreted as an integer
    报错内容:Traceback(mostrecentcalllast):File"C:\Users\xuan\.conda\envs\pytorch1-6\lib\site-packages\scipy\sparse\_sputils.py",line225,inisintlikeoperator.index(x)TypeError:'numpy.float64'objectcannotbeinterpre......
  • 在java 中, 如果三目运算符 是个函数,函数是一定会被执行吗
    在Java中,如果三目运算符中的取值是一个函数,函数不一定会被执行。这取决于三目运算符的条件表达式的结果。如果三目运算符的条件表达式的结果为true,那么执行函数并返回其结果;如果条件表达式的结果为false,那么不执行函数,直接返回另一个值。下面是一个示例代码:intx=5;int......
  • 27基于java的学生在线考试系统
    一、项目简介随着互联网迅速发展,人们的生活已经越来越离不开互联网,人们足不出户就可以工作、学习等。对于在校学生,通过网络教育不仅可以随时进行网络学习,也可以根据学习的情况自我检测,有利于学生高效、快捷地掌握所学的知识。本系统预设计的基于网络的学生自测系统将实现多种用......
  • Java获取pdd详情api接口、商品详情、商品描述、宝贝链接获取展示示例
    ​拼多多商品详情就是对拼多多商城中的宝贝的描述了,消费者们在进入到宝贝的详情页面后,可以通过这些描述去了解该款宝贝。其实这样也可以大大的增加商品的转化率。那么它的作用有什么呢?1.突出商品卖点:把商品的特色和突出点写表现出来,很更好的吸引到顾客,让顾客有点击和购买的欲......
  • 一统天下 flutter - widget 自定义: 通过 SingleChildRenderObjectWidget 实现自定义
    源码https://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widget自定义:通过SingleChildRenderObjectWidget实现自定义组件示例如下:lib\widget\custom\single_child_render_object_widget.dart/**通过SingleChildRenderObjectWidget实现自......
  • java中static方法不能被重写但是能重定义
    1、static方法不能被重写示例1classAnimal{publicstaticvoidwalk(){System.out.println("Animal的行走方法");}}classDogextendsAnimal{publicvoidwalk(){System.out.println("Dog的行走模式");}publicstaticv......