【java】Object类详细分析

API中对Object的介绍

  • Class {@code Object} is the root of the class hierarchy.(类Object是类层次结构的根类)
  • Every class has {@code Object} as a superclass. All objects,(每一个类都要将Object类作为父类)
  • including arrays, implement the methods of this class.(所有对象,包括数组在内,都要实现这个类中的方法)

Object类中包含的成员变量和方法简介

Object类中不包含成员变量,只包含13个方法

这里写图片描述

naive关键字

因为java中有很多地方都使用naive关键字,因此在这里简单总结一下,总结的内容来自:http://blog.csdn.net/youjianbo_han_87/article/details/2586375

  • native关键字是与C++联合开发的时候用的,java自己开发不用!
  • 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。这个函数的实现提在DLL中,JDK的源代码中并不包含,所以看不到被这个关键字修饰的函数的源代码。对于不同的平台它们是不同的。这也是java的底层机制,实际上java就是在不同平台上调用不同的native方法实现对操作系统的访问。
  • native是用做java和其他语言(如C)进行协作时用的,也就是native后的函数的实现不是用java写的。
  • native的意思就是通知操作系统,这个函数你必须给我实现,因为我要用。所以native关键字的函数就是操作系统实现的,java只能调用。
  • java是跨平台的语言,既然是跨平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了

Object类中的方法

首先看一下java.lang.Object中的源码:

public class Object {
   

    private static native void registerNatives();
    
    static {
   
        registerNatives();
    }
    
    public final native Class<?> getClass();
    
    public native int hashCode();
    
    public boolean equals(Object obj) {
   
        return (this == obj);
    }  
    protected native Object clone() throws CloneNotSupportedException;
    
    public String toString() {
   
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }  
    
    public final native void notify();
    
    public final native void notifyAll();
    
    public final native 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 of range");
        }

        if (nanos > 0) {
   
            timeout++;
        }

        wait(timeout);
    }
    
    public final void wait() throws InterruptedException {
   
        wait(0);
    }
    
    protected void finalize() throws Throwable {
    }

类构造器

在类定义过程中,对于未定义构造函数的类,默认会有一个无参的构造函数,Object作为所有类的基类,在源码中,并未给出显示的构造函数,但是实际上,此构造函数是存在的。是JVM自动生成的。


1. private static native void registerNatives()方法

主要作用是将C/C++中的方法映射到java中的native方法,实现方法命名的解耦。在Object类中,在该方法的声明后有一段静态代码块,用来调用该方法:

private static native void registerNatives();  
static {
     
     registerNatives();  
}  

2. public final nativeClass<?> getClass()方法

该方法也是native方法,返回的是该Object对象的类对象/运行时类对象。

类对象: 在java中,类是对具有一组相同特征或者行为的实例的抽象并进行描述,对象是该类所描述的特征或者行为的具体实例。作为概念层次的类,其本身也具有某些共同的属性,如都具有类型、类加载器、包、超类、属性、方法等。java中有专门定义一个类,Class,该类用于描述其他类所具有的这些特征。因此,从该角度来看,类本身也都是属于Class类的对象。 该部分涉及到反射的知识


3. public native int hashCode()方法

hashCode的API说明:

  1. Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in 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.
    在java应用程序执行期间,在对同一个对象多次调用hashCode方法时,必须返回相同的整数。前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
  2. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
    如果根据equals(Object)方法,两个对象是相等的,那么对这两个对象调用hashCode方法都必须生成相同的整数结果。
  3. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
    如果根据equals(java.lang.Object)方法,两个对象不同等,那么对这两个对象中的任意一个对象调用hashCode方法时,不要求一定生成不同的整数结果
    就是说:两个对象不等,那么hashCode可以相等也可以不等;hashCode不等,两个对象一定不等

hashCode返回的值:一般是通过将该对象的内存地址转换成一个整数来实现。该方法不是java实现的,因此使用了native关键字。

hashCode的出现主要是用于增强哈希表的性能:

以集合类中,以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode()方法,需要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。通过借助于hasCode方法,先计算出即将新加入对象的哈希码,然后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象即可


4. public boolean equals(Object obj)方法
equals()方法的内部原理
public boolean equals(Object obj) {
   
    return (this == obj);
}  

这是Object类中提供的equals()方法的源码,通过该源码可以看出,equals内部是通过使用==运算符进行判断两个对象是否相等的。

equals()方法与==运算符

==运算符在比较基本数据类型和引用数据类型的时候含义是不同的:

  • 基本数据类型之间的比较,应用==运算符,比较的是他们的值
  • 引用数据类型用==运算符比较的时候,比较的是在内存中的存放地址,所以,除非是实例化的同一个对象比较后的结果才能是true,否则比较的结果是false**
  • String类等包装类,都对equals方法进行了重写,所以现在调用String类的该方法,比较的是内容是否相等。
  • 当一个类的equlas()方法被重写时,通常需要重写hashCode方法,以维护hashCode方法最开始的声明,即相等的两个对象必须拥有相等的哈希码<-这个理由在下面一节中会具体讲解

比较两个自定义类的时候,如果没有重写equals()方法,那么比较的就是内存地址是否相等。

public class EqualsTest {
   
	public static void main(String[] args){
   
		Bird b1 = new Bird(1);
		Bird b2 = new Bird(1);
		System.out.println("b1.equals(b2):" + b1.equals(b2))
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值