JAVA学习---Object类

Posted 易小顺

tags:

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

Object类

1、 简介

  Object类是Javajava.lang包下的核心类,是类层次结构的根,Object类是所有类的父类,任何一个类都间接或直接继承至Object类,所有对象(包括数组)都实现此类的方法。

  如果一个类没有直接明确继承哪一个类,那么它就是Object的直接子类。

	// 隐式继承
	class People {
	    //
	}
	// 显示继承
	class Student extends Object {
	    //
	}
	System.out.println(new People() instanceof Object);   // true
	System.out.println(new Student() instanceof Object);  // true

  Object 类属于java.lang包,此包下的所有类在使用时无需手动导入,系统会在程序编译期间自动导入,因此在使用Object进行数据的转换时,直接使用就行。

2、 作用

  由于Object作为所有类的父类,因此可以接受所有的 引用数据类型,通过向下转型进行使用。

	class People {
	    // 姓名
	    private String name;
	    public People() {
	        this.name = "王小二";
	    }
	    public void print() {
	        System.out.println(this.name);
	    }
	}
	Object object = new People();
	((People) object).print();  // 王小二

3、 方法解释

 3.1、 方法摘要

变量和类型方法描述
Object()构造方法,构造一个新对象
protected Objectclone()创建并返回此对象的副本
booleanequals(Object obj)指示某个其他对象是否“等于”此对象
protected voidfinalize()过时
Class<?>getClass()返回此 Object的运行时类
inthashCode()返回对象的 哈希码值
voidnotify()唤醒正在此对象监视器上等待的一个线程
voidnotifyAll()唤醒等待此对象监视器的所有线程
StringtoString()返回对象的 字符串 表示形式
voidwait()导致当前线程进入 WAITING 状态,等待其他线程 唤醒 或是被 中断,会释放对象锁
voidwait(long timeoutMillis)wait() 方法一致,只是在等待timeoutMillis时间后没有通知就会自动超时返回
voidwait(long timeoutMillis, int nanos)对于超时时间有着更细粒度的控制

 3.2、 方法详情

  3.2.1 、toString()

  返回一个字符串,类 Object 对象的 toString 返回值由该对象为实例的类的名称、符号字符 @ 以及对象的哈希码的无符号十六进制表示形式组成,也就是返回一个表示该对象的 的字符串。

  • 内部源码
	public String toString() {
	        return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
	    }
  • 代码测试
	Object object = new Object();
	object.toString();  // java.lang.Object@129a8472
  • 建议所有自定义的类都覆写该方法,返回能有效表示当前方法的字符串信息。
	// 以People类为例
	@Override
		// 覆写toString方法,返回当前对象的信息
	    public String toString() {
	        return "People{" +
	                "name='" + name + '\\'' +
	                '}';
	    }

  3.2.2 、equals(Object obj)

  指示某个对象是否 等于 此对象,类 Object 对象的 equals 实现最具有区别的等价关系,也就是说任何非空的对象 xy ,当且仅当 xy 指向同一块地址内存时,才返回 true (也就是内部实现 == 操作)。

  • 内部源码
	public boolean equals(Object obj) {
	        return this == obj;
		}
  • 代码测试
	Object obj1 = new People();
	Object obj2 = new People();
	Object obj3 = obj1;
	obj1.equals(obj2);    // false
	obj1.equals(obj3);    // true
	obj1 == obj2;		  // false
	obj1 == obj3;		  // true
  • 覆写方法,实现自定义类的比较(同时覆盖 hashCode 方法,以便维护 hashCode 方法的常规协定,声明相等的对象必须具有相等的 hash 值)。
	@Override
	    public boolean equals(Object o) {
	        if (this == o) return true;
	        if (o == null || getClass() != o.getClass()) return false;
	        People people = (People) o;
	        return name.equals(people.name);
	    }
  • equals方法在非null对象引用上实现等价关系。
关系解释
对称性对于任何非空的对象xx.equals(x)应该返回true
自反性对于任何非空对象xyx.equals(y)应该返回true当且仅当y.equals(x)返回true
传递性对于任何非空对象xyz,如果x.equals(y)返回truey.equals(z)返回true ,然后x.equals(z)应该返回true
一致性对于任何非空对象xy ,多次调用x.equals(y)始终返回true或始终返回false,前提是未修改对象上的equals比较中使用的信息
非空性对于任何非空的参考值xx.equals(null)应该返回false

  3.2.3 、hashCode()

  返回对象的哈希码值,也就是通过对关键字的 hash 运算,计算在 hash表 中的的存储位置,并非对象的 物理地址

  • 内部源码 是本地方法。
	@HotSpotIntrinsicCandidate
	public native int hashCode();
  • 代码测试
	Object obj = new People();
	obj.hashCode();   // 未进行覆写 453211571
  • 覆写equals 所比较的属性作为关键字,保证相同的对象具有一样的哈希码值。
	@Override
	    public int hashCode() {
	        return Objects.hash(name);
	    }
	Object obj = new People();
	obj.hashCode();   // 进行覆写 29176135
  • hashCode的规则。
结论
只要在执行Java应用程序期间多次在同一对象上调用它, hashCode 方法必须始终返回相同的整数,前提是不修改对象上的 equals 比较中使用的信息。 从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致。
如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每个对象调用hashCode 方法必须生成相同的整数结果。
如果两个对象根据不相等 equals(Object) 方法,然后调用 hashCode 在各两个对象的方法必须产生不同的整数结果,不等对象生成不同的整数结果可能会提高哈希表的性能。
hashCode 返回的整数值相同,其equals(Object)方法不一定相同

  3.2.4 、getClass()

  返回此 Object 的运行时类,返回的类对象是由所表示的类的 static synchronized 方法锁定的对象(也就是返回当前对象所指向的类的类名,引用改变时,相应的返回值也会改变)。

  • 内部源码
	@HotSpotIntrinsicCandidate
	public final native Class<?> getClass();
  • 代码测试
	Object obj = new Object();
	obj.getClass();				// class java.lang.Object
	obj = new People();
	obj.getClass();				// class People

  3.2.5 、clone()

  创建并返回此对象的副本,和原对象不指向同一块地址。

  首先,如果此对象的类未实现接口Cloneable ,则抛出CloneNotSupportedException 异常,因此在实现此功能时需要继承 Cloneable 接口,这是一个标记接口,不需要实现方法。

  • 内部源码
	@HotSpotIntrinsicCandidate
	protected native Object clone() throws CloneNotSupportedException;
  • 方法实现 我们不能直接覆写 clone 方法,因为他是受保护权限修饰的,因此我们需要定义一个public 权限修饰的 clone 方法,来调用父类的该方法进行数据获取。
	public Object clone() {
	        People copy = null;
	        try {
	            copy = (People) super.clone();
	        } catch (CloneNotSupportedException e) {
	            e.printStackTrace();
	        }
	        return copy;
	    }
  • 代码测试
	People people = new People();
	people.clone() == people;						// false
	people.clone().getClass() == people.getClass(); // true
	people.clone().equals(people);					// true
  • 请注意,所有数组都被视为实现接口 Cloneable 并且数组类型 T[]clone 方法的返回类型是 T[] ,其中T是任何引用或基本类型。 否则,此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样; 这些字段的内容本身不会被克隆。 因此,该方法执行该对象的“浅拷贝”,而不是“深拷贝”操作。

  3.2.6 、wait()

  导致当前线程进入 WAITING 状态,等待其他线程 唤醒 或是被 中断。在执行两个方法时,要先获得锁,当线程执行wait()时,会把当前的锁释放,然后让出CPU。

wait() 内部调用 wait(long timeoutMillis)方法,只是时间设置为0

wait(long timeoutMillis, int nanos) 对时间有着更加精确的设置,第一个 long 时间精确为毫秒,第二个 int 时间精确为纳秒。

  • 内部源码
	public final void wait() throws InterruptedException {
	        this.wait(0L);
	    }
	public final native void wait(long var1) throws InterruptedException;
  • 代码测试
学完多线程之后再做补充

  3.2.7 、notify()

   用于唤醒一个在此对象监视器上等待的线程, 如果所有的线程都在此对象上等待,那么只会选择一个线程,选择是任意性的,并在对实现做出决定时发生。

  一次只有一个线程可以拥有对象的监视器。

此方法只应由作为此对象监视器所有者的线程调用。 线程以三种方式之一成为对象监视器的所有者

    • 通过执行该对象的同步实例方法。

    • 通过执行在对象上同步的 synchronized 语句的主体。

    • 对于类型为 Class 的对象,通过执行该类的同步静态方法。

  • 内部源码

	@HotSpotIntrinsicCandidate
	public final native void notify();
  • 代码测试
学完多线程之后再做补充

  3.2.8 、notifyAll()

  和 notify 功能类似,唤醒等待此对象监视器上的所有线程。

  • 内部源码
	@HotSpotIntrinsicCandidate
	public final native void notifyAll();
  • 方法测试
学完多线程之后再做补充
tIntrinsicCandidate
public final native void notify();
  • 代码测试
学完多线程之后再做补充

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

java学习记录笔记--继承,super,Object类

java学习中,object 对象的使用(toStringequalshashCode)(java 学习中的小记录)

Java学习笔记3.5.4 继承 - Object类

java源码学习-详解Object类

JAVA学习---Object类

Java的API及Object