Java中的Object类
Posted 快到锅里来呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的Object类相关的知识,希望对你有一定的参考价值。
目录
🐲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 子句 t 在Object
中声明,除非接口显式声明了具有相同签名、相同返回类型和兼容 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]
但是,接口不会implements
、extends
或“继承自” 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类的主要内容,如果未能解决你的问题,请参考以下文章