Java进阶之Object类及常用方法详解
作者:橙子!
1. Object类
Object 类是 Java 默认提供的一个类,是所有 Java 类的祖先类,每个类都使用 Object 作为父类。
那么我们就可以使用 Object 类的引用变量指向任何类的对象。在没有明确给出一个类的父类时,Java 默认把 Object 类作为该类的父类,继承了 Object 类的所有方法。
示例:
public class Test { public static void main(String[] args) { function(new Person()); function(new Student()); } public static void function(Object obj){ System.out.println(obj); } } class Person{ private int age; private String name; } class Student{ private int grade; private String sno; }
在上面创建了两个不同类型的对象,并且作为实参传递给了 function 方法,此时相当于:
Object obj =new Person();
输出的是对象引用的值,也就是其指向对象的地址。
2. 常用的方法
Object 类中提供了一些方法,其中常用的方法有 toString()
方法,equals()
方法,hashcode()
方法等。在使用前导入 Object 类:
import java.util.Objects;
2.1 toString 方法
JDK源码中的toString方法:
//Object类中的toString()方法实现: public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
toString()
方法定义在 Object 类中,返回值是 String 类型,根据调用它的对象返回类名和它的引用地址。
示例:
public class Test { public static void main(String[] args) { Person person=new Person(); System.out.println(person.toString()); System.out.println(person); } } class Person{ public String name; }
在我们打印对象的引用时,实际上是默认调用了这个对象的toString
方法。返回此对象所在的类及对应的堆空间对象实体的首地址值。
该方法一般要重写后使用,一般重写是将类的对象的属性返回。在没有被重写时,返回的字符串格式是 类名@哈希值,哈希值是十六进制的。示例:
public class Test { public static void main(String[] args) { Person person=new Person(); System.out.println(person.toString()); System.out.println(person); } } class Person{ private String name="张三"; private int age=20; public String toString(){ return "Person:name "+name+" age "+age; } } /* Person:name 张三age 20 Person:name 张三age 20 */
2.2 equals 方法
JDK 源码中的equals()
方法:
// Object类中的equals方法 public boolean equals(Object obj){ return (this == obj); // 使用引用中的地址直接来进行比较 }
equal()
方法定义在 Object 类中,返回值是 boolean 类型,其作用是比较两个对象在堆区的地址是否相同。示例:
public class Test { public static void main(String[] args) { Person person1=new Person("张三",18); Person person2=new Person("李四",20); boolean b=person1.equals(person2); System.out.println(b); } } class Person{ private String name; private int age; public Person(String name,int age){ this.name=name; this.age=age; } } /* false */
需要注意的是比较的是两个引用的值是否相同,即引用执行的地址。如果想要比较对象中的内容,可以重写该方法实现。示例:
public class Test { public static void main(String[] args) { Person person1=new Person("张三",18); Person person2=new Person("张三",18); boolean b=person1.equals(person2); System.out.println(b); } } class Person{ private String name; private int age; public Person(String name,int age){ this.name=name; this.age=age; } @Override public boolean equals(Object obj) { //判断是否为空 if (obj == null) { return false ; } if(this == obj) { return true ; } // 不是Person类对象 if (!(obj instanceof Person)) { return false ; } Person per = (Person) obj ; // 向下转型,比较属性值 //此时比较时按照重写后的equal()方法的规则 return this.name.equals(per.name) && this.age==per.age ; } } /* true */
此时,我们重写了equals()
方法,用来比较对象中的内容是否相同,这部分比较难,可以仔细推敲这段代码,理解其含义。
2.3 hashcode 方法
JDK源码中的hashcode()
方法:
public native int hashCode();
hashcode()方法定义在Object类中,用于放回对象的 hash 代码值,确定对象在内存中存储的位置是否相同。
重写该方法使用:
import java.util.Objects; public class Test { public static void main(String[] args) { Person person1=new Person("张三",18); Person person2=new Person("张三",18); System.out.println(person1.hashCode()); System.out.println(person2.hashCode()); } } class Person{ private String name; private int age; public Person(String name,int age){ this.name=name; this.age=age; } @Override public int hashCode() { return Objects.hash(name, age); } } /* 24022538 24022538 */
事实上 hashCode() 在散列表中才有用,在其它情况下没用,在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
3. 注意事项
重写 equals() 方法时,也必须重写 hashcode() 方法吗?
答:必须,hashCode 和 equals 两个方法是用来协同判断两个对象是否相等的,采用这种方式的原因是可以提高程序插入和查询的速度,当重写equals方法后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中相同对象必须有相同哈希值的约定。
== 和 equals 的区别是什么?
答:对于基本类型和引用类型 == 的作用效果是不同的,如下所示:
基本类型:比较的是值是否相同;
引用类型:比较的是引用是否相同
例如在比较两个字符串时:
public class Test { public static void main(String[] args) { String s1=new String("HelloWorld"); String s2=new String("HelloWorld!"); String s3="HelloWorld"; System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3)); } }
运行结果是
false
true
为什么会出现这样的结果呢?这里就引出了一个新的概念,字符串常量值。字符串有两种赋值方式,一种是字面值的方式赋值,另一种是 new 一个新的对象,这两种方式在性能和内存方面都存在差异。
当使用字面值的方式创建一个对象时,JVM 会在字符串常量池中寻找是否存在这个对象 "HelloWorld"
,如果不存在,则创建这个对象,并将这个对象的引用地址返回给字符串常量 s3,如果存在,则不创建对象,直接返回池中这个对象的地址。这样我们就不难理解上面这段的代码为什么会出现这样的情况了!
4. 总结
Object 类是 Java 默认提供的一个类,是所有 Java 类的祖先类,每个类都使用Object作为父类。Object 类中提供了一些方法,这些方法为了达到想要的效果,我们一般在类中重写使用!
到此这篇关于Java进阶之Object类及常用方法详解的文章就介绍到这了,更多相关Java Object类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!