博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Object详解
阅读量:6615 次
发布时间:2019-06-24

本文共 4466 字,大约阅读时间需要 14 分钟。

hot3.png

我们都知道:在Java中,所有的类都继承了Object这个基类,并且大家都知道,Object有几个比较通用的方法,如equals(),clone(),toString(),我们需要在使用它们的时候进行覆写,今天,我们就具体的探究下这几个方法。

void registerNatives()

这是个Native方法,在静态块中调用,其目的是将hashCode,wait,notify,notifyAll和clone方法注册到本地。

Class<?> getClass()

同样是个Native方法,获取对象的Class。

int hashCode()

Native方法,生成哈希码,其中注意三点

  • 一个对象在同一个进程被多次调用,但是它的哈希码仍然应该是相同的。但是,当同一个对象在不同进程中执行,则哈希码有可能不同。JavaDoc原文如下

    Whenever it is invoked on the same object more than once during an execution of a Java application, the {@code hashCode} method must consistently return the same integer, provided no information used in {@code equals} comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

  • 如果两个对象通过equals()比较返回true,那么它们的哈希码应该相同。

  • 如果两个对象通过equals()比较返回false,那么它们的哈希码应该不同。

boolean equals(Object obj)

这恐怕使我们最常用的方法之一了,我们在实际应用中,也经常遇到什么时候用equals(),什么时候用==的问题。一般来说,基本数据类型用==,因为这样可以直接比较它们的值,但是复合数据类型如果我们用==的话,那么实际上我们比较的就是它们的引用了,除非它们指向的是同一个对象,否则它们不可能相等,因此我们比较符合数据类型一般用equals(),并且我们应该覆写equals(),这是因为Object的equals()方法默认的也是用==进行判定:

public boolean equals(Object obj) {    	return (this == obj);	}

我们再来看看我们经常用的String是如何覆写equals()方法的:

public boolean equals(Object anObject) {    if (this == anObject) {        return true;    }    if (anObject instanceof String) {        String anotherString = (String)anObject;        int n = value.length;        if (n == anotherString.value.length) {            char v1[] = value;            char v2[] = anotherString.value;            int i = 0;            while (n-- != 0) {                if (v1[i] != v2[i])                    return false;                i++;            }            return true;        }    }    return false;}

在这里还有一个很有趣的问题,请看下面的例子

String s1 = "String";    String s2 = "String";    System.out.println("The result is " + s1.equals(s2));

你会发现返回值为True,这个就和我们上面讲的不一样了,按照我们上面的讲解,这时候应该返回false才对。其实是这样的,因为JVM中会维护一个字符串池,如果池中已经有包含此对象的字符串的时候,那么它就会返回池中的字符串(当然如果你new一个新的String对象的话就另当别论。)所以这个时候返回的是true。

###Object clone() Native方法,我们一般用它来复制一个对象,并且用clone()可以实现深复制(将所有需要复制的对象都复制了一遍,而不单单是用引用指向原来的对象。)示例如下:

public class Animal implements Cloneable {    private int height;    private int age;    public Animal(int height, int age){        this.height = height;        this.age = age;    }    @Override    public Object clone() throws CloneNotSupportedException {        return super.clone();    }    @Override    public String toString() {        return "Animal{" +                "height=" + height +                ", age=" + age +                '}';    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}public class People implements Cloneable {    private int height;    private int age;    private Animal a;    public People(int height, int age,Animal a){        this.height = height;        this.age = age;        this.a = a;    }    @Override    public Object clone() throws CloneNotSupportedException {        People p = (People) super.clone();        p.a = (Animal) a.clone();        return p;    }    @Override    public String toString() {        return "People{" +                "height=" + height +                ", age=" + age +                ", a=" + a +                '}';    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public void setAnimalAge(int a) {        this.a.setAge(5);    }}

接下来我们这样调用:

Animal a1 = new Animal(100,3);    People p1 = new People(173,24,a1);    People p2 = (People) p1.clone();    p2.setAge(26);    p2.setHeight(181);    p2.setAnimalAge(6);    System.out.println(p1.toString());    System.out.println(p2.toString());

这样我们就完成深复制了。

String toString()

最常用的方法,我们一般用它获取对象成员变量的值。Object的默认实现:

public String toString() {    return getClass().getName() + "@" + Integer.toHexString(hashCode());}

void notify(),void notifyAll()

Native方法,多线程时应用,通知其他线程等待结束。

void wait(long),void wait(long,int),void wait()

Native方法,通知线程等待。

void finalize()

垃圾回收。当JVM判断一个对象可以被垃圾回收时,那么JVM会调用finalize()方法,但是记住,它只能调用一次(所以如果你想这个对象不被垃圾清除的话,你就要在这里面做点事情了),但是一般你不能依赖在这里做垃圾回收的工作,在《Java编程思想》中说明了有关finalize()的一个用法,那就是通过finalize()来进行对象终结对象的判断。

转载于:https://my.oschina.net/weiCloudS/blog/420224

你可能感兴趣的文章
关于IT服务管理的服务台
查看>>
rundeck 修改密码 添加节点
查看>>
解决Nginx不支持ThinkPHP配置PATHINFO问题
查看>>
用R语言做数据分析(7)——数据的输入与输出之Scan函数
查看>>
IT讲师韩顺平:创业不易,尚硅谷延续教育初心
查看>>
IntelliJ IDEA 插件 阿里巴巴Java开发手册
查看>>
利用nmap对Mongodb Redis未授权访问测试
查看>>
CakePHP
查看>>
我的友情链接
查看>>
sample-envoy-proxy
查看>>
编译mysql5.6.27
查看>>
搭建centos6.7网站服务器记录
查看>>
我的友情链接
查看>>
Release版本调用ffmpeg av_register_all程序崩溃
查看>>
【CetOS 7LAMP架构6】,Apache默认虚拟主机#171220
查看>>
我的友情链接
查看>>
Referenced management pack not found
查看>>
jquery中data函数的用法示例
查看>>
巧用strtotime函数计算日期
查看>>
JVM中java对象的生命周期
查看>>