【Java编程进阶】Object类及常用方法详解

在这里插入图片描述

Java 编程基础教程系列:Java 编程进阶之路【从入门到精通】 ,从入门到精通一站学习,买不了吃亏,买不了上当!!


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="HelloWorld!";
       String s2=new String("HelloWorld!");
       String s3="HelloWorld!";
       System.out.println(s1==s2);
       System.out.println(s1==s3);
    }
}

运行结果是

false
true

为什么会出现这样的结果呢?这里就引出了一个新的概念,字符串常量池。字符串有两种赋值方式,一种是字面值的方式赋值,另一种是 new 一个新的对象,这两种方式在性能和内存方面都存在差异。

当使用字面值的方式创建一个对象时,JVM 会在字符串常量池中寻找是否存在这个对象 "HelloWorld",如果不存在,则创建这个对象,并将这个对象的引用地址返回给字符串常量 s3,如果存在,则不创建对象,直接返回池中这个对象的地址。这样我们就不难理解上面这段的代码为什么会出现这样的情况了!

4. 总结

Object 类是 Java 默认提供的一个类,是所有 Java 类的祖先类,每个类都使用Object作为父类。Object 类中提供了一些方法,这些方法为了达到想要的效果,我们一般在类中重写使用!


在这里插入图片描述

欢迎订阅学习Java编程进阶之路专栏专栏文章持续更新!

猜你喜欢

转载自blog.csdn.net/zhangxia_/article/details/128526807