java Object类
java Object类
概要
java.lang.Object类是Java当中所有类的基类,即所有类的父类,它里面描述的所有方法,子类都可以使用。在对象实例化的时候,最终找的父类就是Object。
Object包含了9大常用方法: getClass()、 hashcode()、 toString()、equals()、finalize()、notify()、notifyAll()、wait()、clone()
一、toString()
public String toString():返回该对象的字符串表示。
toString方法返回该对象的字符串表示,其实该字符串内容就是:对象的类型名+@+内存地址值。
查看源码:
1 public String toString() { 2 3 return getClass().getName() + "@" + Integer.toHexString(hashCode()); 4 5 }
由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。
比如:
1 public static class Student { 2 3 public String name; 4 public Integer age; 5 6 public Student(String name, Integer age) { 7 this.name = name; 8 this.age = age; 9 } 10 11 @Override 12 public String toString() { 13 return "Student{" + "name='" + name + "'" + ", age=" + age + '}'; 14 } 15 }
二、equals()
方法摘要:
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
调用成员方法equals并指定参数为另一个对象,则可以判断这两个对象是否是相同的。
查看源码:
1 public boolean equals(Object obj) { 2 3 return (this == obj); 4 5 }
可以看出,Object类中的equals()方法也是比较引用是否相同。那么,想要比较值是否相同,该怎么办呢?这就需要重写equals()。
重写equals,要注意以下几点注意事项:
1) 对任意x,x.equals(x)一定返回true
2)对任意x,y,如果x.equals(y)返回true,则y.equals(x)也一定返回true
3)对任意x,y,z,如果x.equals(y)返回true,y.equals(z)也返回true,则x.equals(z)也一定返回true
4)对任意x,y,如果对象中用于比较的信息没有改变,那么无论调用多少次x.equals(y),返回的结果应该保持一致,要么一直返回true,要么一直返回false
5)对任意不是null的x,x.equals(null)一定返回false
另外,重写了equals(),还需要重写hashcode(),如果两个对象equals()方法相等,则他们的hashcode返回值一定要相同
三、native本地方法
在Object类的源码中定义了 native 修饰的方法, native 修饰的方法称为本地方法。
本地方法的作用: 就是Java调用非Java代码的接口。方法的实现由非Java语言实现,比如C或 C++。
被native修饰的本地方法我们无法查看源码。
1、hashcode()
1 public native int hashCode();
功能:用于返回对象的哈希码。哈希码是一个整数值,通常用于快速确定对象在哈希表等数据结构中的存储位置。
什么是hashcode: 在Java及大多数面向对象的语言中,每一个对象都有属于自己的hashcode,这个hashcode是区分不同对象的重要标识
说明:
1) 提供对象的哈希码
hashCode() 方法返回一个 int 类型的哈希码值,该值通常由对象的内容计算而来。不同对象的哈希码可能不同,但相同对象的哈希码应该相等。
2)在散列表中使用
散列表(如哈希表)是一种常见的数据结构,用于快速查找和存储数据。哈希码可用作散列表中的键,帮助确定对象在表中的存储位置。
3)支持哈希集合
哈希集合(如 HashSet)和哈希映射(如 HashMap)是基于哈希码实现的数据结构,用于存储唯一的对象或键值对。通过正确实现 hashCode() 方法,可以确保对象在这些集合中能够正确地存储和检索。
java中哈希码有以下约定:
在同一个java程序执行过程中,不论调用hashCode方法多少次,都要返回相同的值,
两个对象的equals方法相同,hashCode方法一定相同,
两个对象的equals方法不相同,hashCode方法不一定不同,
两个对象的hashCode方法不相同,equals方法一定不同,
两个对象的hashCode方法相同,equals方法不一定相同。
说明:如果两个对象的hashCode返回值相同,但它们的equals()方法却有可能最终返回false,这种情况叫做hash碰撞。
2、getClass()
1 public final native Class<?> getClass();
功能:getClass方法用于获取一个对象的运行时类(Class),进而通过返回的Class对象,获取该类的相关信息,比如获取该类的构造方法、该类有哪些方法、该类有哪些成员变量等信息。
尽管 Java 和 Android 都运行 Java 代码,但由于使用了不同的虚拟机实现,它们在内存管理方面可能有所差异。不同VM针对class做了不同的优化,所以getClass()的实现也并不相同,比如:
1 // Java用native方法实现 getClass() 2 public final native Class<?> getClass(); 3 4 // Android 特殊的实现方式 5 private transient Class<?> shadow$_klass_; 6 public final Class<?> getClass() { 7 return shadow$_klass_; 8 }
Java默认的Hotspot虚拟机并没有开辟单独的Method Area空间,而是由GC Heap的老生代的Metaspace实现的。而Android采用ART VM,这才造成了这种差异。
3、clone()
1 protected native Object clone() throws CloneNotSupportedException;
功能:Object.clone()是用于创建对象的浅拷贝的方法
说明:浅拷贝意味着它只复制对象本身和其所有引用的内容,而不会递归地复制引用的对象。具体来说,clone()
方法会创建一个新的对象,并将原始对象的所有字段值复制到新对象中,但是对于对象的引用类型字段,它们只会被复制引用,而不会复制引用的对象本身。
注意事项:
要想使用 clone()
方法进行拷贝,被拷贝的对象必须实现 Cloneable
接口(Cloneable是一个标识接口,标识这个类的对象是可被拷贝的),否则会抛出 CloneNotSupportedException
异常。
举个例子:
1 class MyClass implements Cloneable { 2 private int value; 3 private String text; 4 5 public MyClass(int value, String text) { 6 this.value = value; 7 this.text = text; 8 } 9 10 // 重写clone()方法 11 @Override 12 public Object clone() throws CloneNotSupportedException { 13 return super.clone(); 14 } 15 16 // Getters and setters 17 public int getValue() { 18 return value; 19 } 20 21 public void setValue(int value) { 22 this.value = value; 23 } 24 25 public String getText() { 26 return text; 27 } 28 29 public void setText(String text) { 30 this.text = text; 31 } 32 } 33 34 public class Main { 35 public static void main(String[] args) { 36 MyClass original = new MyClass(10, "Hello"); 37 38 try { 39 // 浅拷贝 40 MyClass clone = (MyClass) original.clone(); 41 42 // 修改原始对象的字段值 43 original.setValue(20); 44 original.setText("World"); 45 46 // 输出原始对象和克隆对象的字段值 47 System.out.println("Original: " + original.getValue() + ", " + original.getText()); 48 System.out.println("Clone: " + clone.getValue() + ", " + clone.getText()); 49 } catch (CloneNotSupportedException e) { 50 e.printStackTrace(); 51 } 52 } 53 }