Java日志第23天 2020.7.28

Object类

java.lang.Object类是类层次结构的顶层,每个类都是用Object类作为父类。

所有对象(包括数组)都可以实现这个类中的方法。

1.toString类

String toString() 返回该对象的字符串表示。

直接打印对象的名字,其实就是调用对象的toString方法。

public class People {
    private String name;
    private int age;

    public People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

public class DemoMain {
    public static void main(String[] args) {
        People p = new People("Gazikel",20);
        /*
            People类继承Object类,所以可以使用Object类中的方法
         */
        String s = p.toString();
        System.out.println(s);

        //直接打印对象的名字,其实就是调用toString方法
        System.out.println(p);
    }
}

结果如下:

 

 

打印对象的地址值没有任何的意义,所有需要在类中覆盖重写Object类中的toString方法。

Alt+Insert可以自动覆盖重写这种方法

  /*
    重写toString方法
    打印该类的属性
     */

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

打印结果如下:

 

 

所以我们可以通过输出语句来进行判断某个类是否进行了toString 方法的覆盖重写。

 

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class DemoMain {
    public static void main(String[] args) {
        //任意数
        Random r = new Random();
        System.out.println(r);
        System.out.println("============");
        //输入
        Scanner sc = new Scanner(System.in);
        System.out.println(sc);
        System.out.println("============");

        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        System.out.println(list);
    }
}

结果如下:

java.util.Random@74a14482
============
java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match valid=false][need input=false][source closed=false][skipped=false][group separator=\,][decimal separator=\.][positive prefix=][negative prefix=\Q-\E][positive suffix=][negative suffix=][NaN string=\Q�\E][infinity string=\Q∞\E]
============
[1, 2]

 

可以看到,Random类没有重写toString方法,而Scanner和ArrayList输出结果不是地址值,故它们重写了toString方法。

 

2.equals方法

boolean equals(Object obj) 指示其他某个对象是否与此对象相等

equals源码为:

public boolean equals(Object obj){

  return (this == obj);

}

 返回值类型是一个布尔类型,所以返回true或false

当是基本数据类型比较,则比较它们的大小

当是引用数据类型比较,则比较它们的地址值

public class DemoMain {
    public static void main(String[] args) {
        People p1 = new People("迪丽热巴",20);
        People p2 = new People("古力娜扎",21);

        System.out.println(p1.equals(p2));//false

        p1 = p2;//将p2地址赋给p1

        System.out.println(p1.equals(p2));//true
    }
}

 

 

equals方法只能比较两个对象的地址值,这也是没有意义的,所以我们也要覆盖重写equals方法。有一个问题,将Object类向下转型。

 @Override
    public boolean equals(Object obj) {
        People p =(People) obj;
        boolean b = (this.name.equals(p.name)) && (this.age == p.age);
        return b;
    }

 

 

当如果equals的参数不是重写方法中强制转换的参数时,就会报错。为了避免这种错误,就需要增加一个if语句来进行判断是否可以进行向下转型。

另外,我们还可以增加if语句分别判断参数是否等于null和本身,直接返回一个值,提升程序的效率。

上述所说的代码,不需要我们写,Alt+Insert会自动生成重写的代码。

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        People people = (People) o;
        return age == people.age &&
                Objects.equals(name, people.name);
    }

这里的 getClass() != o.getClass() 是利用反射技术来判断是否可以向下转型,相当于 o instanceof People。

 

Objects类的equals方法

因为null是不能调用方法的。如果使用Object类中的equals方法,并将参数列表中的参数定义为空,则编译器就会抛出空指针异常。

 

public class DemoMain {
    public static void main(String[] args) {
        String s1 = null;
        String s2 = "abc";

        //boolean b = s1.equals(s2);报错
        boolean b = Objects.equals(s1, s2);
        System.out.println(b);

    }
}

结果如下:

 

 

 

问题:equals方法为什么不能对整数进行判断?

*注意这两种方法都有返回值,调用时需要注意

明天学习时间类

 

posted @ 2020-07-28 13:57  Gazikel  阅读(135)  评论(0编辑  收藏  举报