Java中的Object类

Posted 快到锅里来呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的Object类相关的知识,希望对你有一定的参考价值。

目录

🐲1.Object类是什么?

🐲2.Object类中的equals方法

🐲3.Object类中的hashCode方法

🐲4.编译器自动生成equals和hashCode


🐲1.Object类是什么?

🟪Object 是 Java 类库中的一个特殊类,也是所有类的父类

也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。

🟦Java里面除了Object类,所有的类存在继承关系的。

🟩Object 类位于 java.lang 包中,编译时会自动导入, 当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。

class Person 
class Student 
public class Test03 
    public static void func(Object o)   

    public static void main(String[] args) 
        func(new Person());
        func(new Student());
    
    public static void main1(String[] args) 
        Object o = new Person();
        Object o2 = new Student();
    

下面来看一下Object类中都有什么方法

 本篇会简单介绍hashCode(),equals()

🐲2.Object类中的equals方法

下面看这样一段代码

class Person 
    public String dz;
    public Person(String dz) 
        this.dz = dz;
    
    @Override
    public String toString() 
        return "Person" +
                "dz='" + dz + '\\'' +
                '';
    

class Student 


public class Test03 

    public static void main(String[] args) 
        Person person = new Person("beijing");
        Person person1 = new Person("beijing");
        System.out.println(person == person1);

 如果直接这样比较,看地址是否相同,就会输出false,输出是错误的

⚜️那么如果要比较,有什么方法吗

🟪在java中提供了一个方法是equals,可以用来比较两对象是否相同

   System.out.println(person.equals(person1));

如果直接在main中这样写,还是会输出false,

这是因为person里面没有equals,默认是继承于Object的

 可以看到里面比较的还是this和obj,也就是当前传进来的参数,所以才是false。

⚜️那么如何用equals进行比较

🟥那就要重写一个equals才可以进行比较

    @Override
    public boolean equals(Object obj) 
        //判断当前obj参数是否为null
        if (obj == null) 
            return false;
        
        if (this == obj) 
            return true;
        
        //不是Person类对象
        if (!(obj instanceof Person)) 
            return false;
        
        Person ret = (Person) obj;
        return this.dz.equals(ret.dz);
    

🟪我们可以String帮助重写equals了

 此时equals就可以比较了

 

🟥比较对象中内容是否相同的时候 要重写equals


🐲3.Object类中的hashCode方法

🟩使用hashCode可以计算具体的对象位置,也就是内存地址,然后调Integer.toHexString()方法,将这个地址以16进制输出

 

🟫 两个dz是相同的,然后直接用hashCode计算内存地址,然后代码发现,内存地址是不同的

说明直接这样中hashCode是不行的,那就要重新实现一个hashCode,

 下面重写一下hashCode,

    @Override
    public int hashCode() 
        return Objects.hash(dz);
    

然后运行代码试试看,果然重写之后,内存地址相同了

 🦖所以,hashCode是用来定位 位置的

 


🐲4.编译器自动生成equals和hashCode

一般重写时,都是这两个同时进行重写

这就是生成好了的 equals和hashCode

    @Override
    public boolean equals(Object o) 
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(dz, person.dz);
    

java中的接口是不是继承自Object类

【中文标题】java中的接口是不是继承自Object类【英文标题】:Do interfaces inherit from Object class in javajava中的接口是否继承自Object类 【发布时间】:2011-08-28 16:57:20 【问题描述】:

接口是否继承自 Java 中的 Object 类?

如果没有,那么我们如何在接口实例上调用对象类的方法

public class Test 
    public static void main(String[] args) 
        Employee e = null;
        e.equals(null);
    


interface Employee 

【问题讨论】:

@EJP,从技术上讲,java/io/Serializable.class 包含什么并不重要。我认为您将 Java 语言规范与 JVM 规范混淆了。 @aioobe 因为我没有提到这些规范中的任何一个,所以我不明白你的意思。 Serializable 是一个接口,可能是最简单的;在它上面运行javap 会告诉你它继承了什么;这是由 Java 语言规范规定的。如果您认为 JVM Spec 涉及到某个地方,请不吝赐教。 @EJP,问题是关于 Java 语言(即 Java 语言规范)。 java/io/Serializable.class 所包含的内容与 JVM 规范所说的有关。从技术上讲,不能保证两个规范的特征之间存在一一对应的关系。 我在最近的blog post中对此进行了详细说明。 【参考方案1】:

接口没有也不能扩展 Object 类,因为接口必须具有公共和抽象方法。

对于 Object 类中的每个公共方法,接口中都有一个隐式公共和抽象方法。

这是标准的 Java 语言规范,声明如下,

“如果一个接口没有直接的超接口,那么该接口隐式声明一个公共抽象成员方法m,签名为s,返回类型为r,并抛出子句t对应每个签名为s的公共实例方法m,返回类型为r , 以及在 Object 中声明的 throws 子句 t,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的方法。”

【讨论】:

【参考方案2】:

接口继承了Object类,怎么才能通过接口类型引用访问Object类的方法 No Interface 不继承Object 类,但它提供对Object 类的所有方法的可访问性。 接口的成员是:

Those members declared in the interface.
Those members inherited from direct superinterfaces.
If an interface has no direct superinterfaces, then the interface implicitly 

声明了一个公共抽象成员方法,对应于Object类中声明的每个公共实例方法。如果接口在在Object 中将m 声明为final 的情况。

现在很明显,所有的超接口都有abstract成员方法,对应于Object中声明的每个public实例方法。

来源: http://ohmjavaclasses.blogspot.com/2011/11/is-intreface-inherits-object-***ow.html

【讨论】:

【参考方案3】:

接口是否继承自 Java 中的 Object 类?

不,他们没有。并且没有通用的“根”接口被所有接口隐式继承(就像类的情况一样)。(*)

如果没有,那么我们如何在接口实例上调用对象类的方法

接口为Object 中的每个公共方法隐式声明了一个方法。因此equals 方法被隐式声明为接口中的成员(除非它已经从超接口继承了它)。

这在 Java 语言规范§ 9.2 Interface Members 中有详细说明。

9.2 接口成员

[...]

如果接口没有直接的超接口,则接口隐式声明一个公共抽象成员方法m,签名为s,返回类型r,以及每个公共实例方法 m 对应的 throws 子句 t,签名为 s,返回类型 r,以及 throws 子句 tObject 中声明,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的方法。

[...]


此帖已改写为文章here。


(*) 请注意,作为 的子类型 的概念并不等同于 继承:没有超接口的接口确实是 @987654329 的子类型@ (§ 4.10.2. Subtyping among Class and Interface Types ) 即使它们不继承自 Object

【讨论】:

@aioobe 如果我们实现任何接口,那么为什么不在实现该接口的类中实现“equals”方法。根据我的概念,我们必须在实现类中实现接口的方法,否则类将是抽象的。 您不需要(重新)实现继承的方法。看看this example。换句话说,equals 已经定义并继承到实现接口的类。 我明白了。但是有一个问题——我们为什么需要这个?如果Object类的方法没有在接口中声明会有什么不同? 如果我们没有这个,问题中的程序将无法编译。 Employee接口中有equals方法。 这个问题和答案仍然提醒我,即使经历过,我也应该专注于让我的基础更强大。【参考方案4】:

"引用类型都继承自 java.lang.Object。类、枚举、数组和接口都是引用类型。"

引用自:http://docs.oracle.com/javase/tutorial/reflect/class/index.html 第二句要清楚。

【讨论】:

Classes, enums, and arrays (which all inherit from java.lang.Object) as well as interfaces are all reference types :它没有说接口继承自 Object。只有类、枚举和数组。 他们改变了它:) 即使“他们改变了它”(我对此表示怀疑),教程也可能是错误的。规范性参考是 Java 语言规范 (JLS)。【参考方案5】:

Object 是任何接口的超类型 [1]

但是,接口不会implementsextends“继承自” Object

JLS 有一个特殊的子句将Object 方法添加到接口[2]

[1]http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.2

[2]http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.2

【讨论】:

这是最准确的答案。应该是被接受的。例如。采用java.lang.Object 的方法也将接受任何接口类型的引用。此外,您可以将接口隐式转换为Object,而不会出现任何编译器错误。【参考方案6】:

这是因为employee e = ... 读取到有一个类实现 employee,并分配给变量e。每个实现接口的类都隐式扩展 Object,因此当您执行 e.equals(null) 时,该语言知道您有一个类是 employee 的子类型。

JVM 将对您的代码进行运行时检查(即抛出 NullPointerException)。

【讨论】:

【参考方案7】:

每个.class 文件中实际上都有一个超类字段,包括那些表示接口的字段。

对于一个接口,它总是指向java.lang.Object。但这并没有什么用处。

另一种看待它的方式是:

interface MyInterface 
    // ...


public myMethod(MyInterface param) 
    Object obj = (Object) param;
    // ...

这里的转换(Object) param 始终有效,这意味着每个接口类型都是java.lang.Object 的子类型。

【讨论】:

.class 文件是 .java 文件的产物。通过查看生成的 .class 文件来争论为什么某些东西在 Java 语言中有效是向后推理。 对象 obj = (Object) 参数;不会抛出编译错误。但是 MyInterface 的方法(public)对 obj 是不可见的。因此不能假设 MyInterface 是每个接口类型都是 java.lang.Object 的子类型【参考方案8】:

根据定义,任何实现任何接口的类也都派生自Object

【讨论】:

以上是关于Java中的Object类的主要内容,如果未能解决你的问题,请参考以下文章

java -- Object类和String类

在java语言中Object如何成为超类?看完你就懂了

c++与java 的析构函数

Java语言进阶篇基本概念

maven找不到java.lang.object的类文件

java--面对对象之Object类