class括号里的object_JAVA脱水学习-java超类Object解析,Object常用方法

Java 中的父类也称为超类,而 Java 是个面向对象语言,面向对象的基础就是类。Java 中所有类都有一个共同的祖先 Object 类,Object 类是唯一没有父类的类,Object 类引用变量可以存储任何类对象的引用。

f619e06f09e07f46376a346320f24d3b.png

一、Object 类中定义的方法

既然所有类都继承自 Object 类,那么所有类都拥有 Object 类中定义的方法。看下 Object 类中有哪些方法:

// 构造器public Object();// 获取对象的散列码// 可自定义public native int hashCode();// 返回运行时对象的 Class 类型对象// 不能自定义public final native Class> getClass();// 比较对象是否相同,也即引用地址是否指向同一对象// 可自定义public boolean equals(Object obj);// 克隆对象,产生一个新对象。// 可自定义protected native Object clone() throws CloneNotSupportedException;// 返回对象的字符串说明// 可自定义public String toString();// 唤醒一个正在该对象上等待的线程// 不能自定义public final native void notify();// 唤醒所有正在该对象上等待的线程// 不能自定义public final native void notifyAll();// 使当前线程进入等待,直到被唤醒// 不能自定义public final void wait() throws InterruptedException;// 使当前线程进入等待,直到被唤醒或等待超时(毫秒)// 不能自定义public final native void wait(long timeoutMillis) throws InterruptedException;public final void wait(long timeoutMillis, int nanos) throws InterruptedException;// 对象在被释放前调用// 可自定义protected void finalize() throws Throwable;

关于 native 修饰词的说明:

native 修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言中(如 C、C++),所以效率上一般比 java 语言实现的方法要高。Java 本身不能对操作系统底层进行访问和操作,但是可以通过 JNI(Java Native Interface)接口调用其他语言来实现对底层的访问。

JNI 是 Java 本机接口(Java Native Interface),是一个本机编程接口,它是 Java 软件开发工具箱(java Software Development Kit,SDK)的一部分。JNI 允许 Java 代码使用其他语言编写的代码和代码库。Invocation API(JNI 的一部分)可以用来将 Java 虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用 Java 代码。

二、Object 类方法解说

1. public Object() 构造方法

我们都知道,对象是类通过构造器创建的。而普通类可以不实现构造函数,那是因为所有类都是继承自 Object 类,普通类没有构造器时就会调用父类的构造器,即 Object 类中构造器。但是 Object 是个始祖类,没有父类,自己不实现构造器的话就不能创建对象了。所以 Object 类中需要定义一个空的构造函数。

2. public native int hashCode() 获取对象散列码

是个本地方法,不在 Object 类中实现。hashCode 方法返回一个整数,这个整数是对象根据特定算法计算出来的一个散列值(hash 值)。子类可以重写 hashCode 方法,但是重写后 euqals 方法通常也需要重写。而且 hashCode() 和 equals() 方法具有以下特性:

1) 两个对象通过 equals() 判断为 true,则这两个对象的 hashCode() 返回值也必须相同

2) 两个对象的 hashCode() 返回值相同,equals() 比较不一定需要为 true,可以是不同对象。

为什么重写 hashCode() 或 equals() 中的一个方法,另外一个方法也建议重写呢?而且必须具备上面的特性呢?

我们经常会碰到一些需求,如将一类元素放到一个容器里。那么放入容器前,肯定需要知道这个元素是否已在容器中了。对于只存放几个元素的小容器,我们可以循环容器中的每个元素进行 equals() 比较,都是 false 表明不存在,那么就将这个元素放入容器。但当我们需要存放大量数据,而我们又不关心排列顺序时怎么处理,肯定不能一个个循环匹配,这样效率太低。Java 标准库已经提供了一些集合接口实现,其中就有无序集合,如哈希表:hashTable、hashMap 等。

哈希表将数据分成很多块,每一块称之为“桶”,桶的个数是2的幂,默认16个,当然桶的个数可以自定义。当一个新对象 A 需要放入哈希表中时,先取对象 A 的 hashCode 一个整数,再对桶的总数求余。假如余数为3,则将 A 放入第4个桶中。如果第4个桶中没有其它元素,那么这次数据插入很顺利,直接将 A 放入第4个桶中,如果第4个桶中已经存中其它元素了,那么就需要判断 A 是否已存在,这时就遍历桶中的元素,通过 equals() 比较是否相同,都不相同则插入数据,有相同则不插入。新数据插入到末尾,多个数据对象形成一个链表。如图:

1b1e0c442dc83631a4e176021507f435.png

既然桶的个数是固定的,那总会有填满的时候,当桶都填满后,每次插入新数据不是又要整个链表循环比较?为了避免出现这种情况,哈希表有个阈值(装填因子),默认值为 0.75(可以自定义)。当表的 75% 被填入值后,再次插入数据时就会创建一个两倍原桶数的新表,再把旧表数据移到新表,旧表被丢弃。

3. public final native Class> getClass() 返回运行时对象的 Class 类型对象

先看一段示例:

670294d39dc95cc615ebc51d16771b5e.png

可以看出:

1.Person 对象 p 和 Class 对象 cp 都是对象实例。

2.Class 类是继承自 Object 类的。

3.Class 对象 cp 其实是对象 p 的类信息的一个对象。通过 cp 对象可以获取到类 Person 中定义的属性和方法。

所有类都继承自 Object 超类,那么所有对象都可以通过其 getClass() 方法获得生成该对象的类实例,并通过该类实例创建许多相同类型的对象,甚至访问对象的属性或方法。其实这就是 Java 中的反射,而 Class 类是反射得以实现的基础。

定义一个 Person 类:

package human;public class Person implements Cloneable{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; }}

通过 getClass() 获取 Person 的 Class 类对象,并创建新的 Person 对象实例。

package human;import java.lang.reflect.Constructor;public class Main{ public static void main(String[] args) { Person p = new Person("张三
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值