从零开始学Java-常用API:Object、Objects

244 阅读9分钟

目录

  • object
  • objects

object

  • 0bject是Java中的顶级父类。所有的类都直接或间接的继承于0biect类
  • 0bject类中的方法可以被所有子类访问,所以我们要学习0bject类和其中的方法。

image.png

我们先来看一下object有哪些构造方法吧:

构造方法

方法名说明
public object()空参构造

顶级父类中只有无参构造方法,没有带参的构造方法

为什么呢?那是因为在java当中,没有一个属性是所有类的共性,所以说在object这个类当中,没有成员变量的,既然没有成员变量,那就没有带参的构造方法。

成员方法

方法名说明
public string tostring()返回对象的字符串表示形式
public boolean equals(object obj)比较两个对象是否相等
protected obiect clone(int a)对象克隆(拷贝)

我们下面来实操一下吧:

- tostring()

// 1.tostring() 返回对象的字符串表示形式
Student stu = new Student();
String str1 = stu.toString();
System.out.println(str1);

我们来运行看一下是什么效果:

image.png

我不是打印一个字符串嘛,怎么打印出了这串东西呀?其实这是一串地址值。我们来了解一下:

image.png

我们再来看一下toString的源码:

image.png

怎么样,是不是一样的呀。下面我们来了解一下细节吧:

  • 细节:
    • System:类名
    • out:静态变量
    • System.out:获取打印的对象
    • println():方法
    • 参数:表示打印的内容

那我们就想了,默认情况下因为object类中的toString方法返回的是地址值,那我想要看到对应的对象内部属性值怎么办呢?

如果父类的方法不能满足我们的需要,我们是不是可以重写他们的方法呀?

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

这个时候我们来运行看一下:

image.png

这个时候是不是就获取到属性的内部值了呀,由于我们没有给他赋值,所有打印出来的是默认值。我们来给他赋值再次运行看一下:

Student stu = new Student("张三",23);

image.png

这个时候就可以获取到属性的值啦。下面我们来总结一下:

  1. 如果我们打印一个对象,不想要看到地址值,而是看到属性值的话那么就重写toString方法就可以啦。
  2. 在重写方法中,把对象的属性进行拼接。例:return name + "," + age;

- equals(object obj)

我们来看一段代码:

Student s1 = new Student("张三",20);
Student s2 = new Student("张三",20);
boolean result1 = s1.equals(s2);
System.out.println(result1);        // false

你们猜一下运行结果是多少呢?

image.png

是不是false呀,那是为什么呢?我们之前是不是知道了equals比较引用数据类型是比较地址值呀,而这两个对象又是new出来的,所以说地址值是不是不一样呀,所有返回的是false。

那我想比较两个对象的属性值怎么办呢?

父类不能满足我的需求,那我重写不就可以了吗。是的。其实这个重写方式不用我们自己写哟,可以按快捷键FN+ALT+INSERT:

image.png

选择equals(),然后一直Next下一步下一步就可以了。

image.png

到这里可以看到他把全部属性已经勾选上了,我们继续Next下一步。

image.png

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

这个时候就帮我们重写好啦,这些代码是什么意思呢?我们来了解一下:

if (this == o) return true;

他会先判断this跟参数是不是同一个对象,如果就同一个地址值,就返回true。

if (o == null || getClass() != o.getClass()) return false;

这行呢其实就是对非空和类型的一些判断。

Student student = (Student) o;

这行是将参数的o向下强转,强转成Student类型。

return age == student.age && Objects.equals(name, student.name);

这行呢就是比较对象里面的值是否相等了。

到这里我们就知道了,重写之后的equals方法比较的就是对象内部的属性值了。

  • 下面我们来总结几点吧:

    • 1.如果没有重写equals方法,那么默认使用Object方法进行比较,比较的是地址值。
    • 2.一般地址值对我们意义不大,所有我们会重写,重写之后就是比较对象内部的属性值了。

我们再来看个案例:

String s = "abc";
StringBuilder sh = new StringBuilder("abc");
System.out.println(s.equals(sh));
System.out.println(sh.equals(s));

来猜一下运行结果是多少呢?

image.png

两个都是false,为什么呀?不着急我们接着来说一下:

  • System.out.println(s.equals(sh));

因为equals方法是被s调用的,而s是字符串,所有equals要看到string类中的。他会先判断是不是字符串,如果是在比较内部的属性,如果不是字符串,那就直接返回false。

  • System.out.println(sh.equals(s));

因为equals方法是被sh调用的,而s是StringBuilder,所有equals要看到StringBuilder中的equals方法,如果在StringBuilder中没有重写equals方法,那么在Object当中默认是使用==号比较两个对象的地址值,而这里的s和sh记录的地址值不一样,所以返回false。

- clone()

clone():把A对象的属性值完全拷贝给B对象,也叫对象拷贝、复制。

下面我们来实操一下吧:

我们先来定义一个用户的JavaBean类:

private int id;             // 游戏id
private String username;    // 用户名
private String password;    // 密码
private String path;        // 游戏图片
private int[] data;         // 游戏进度

这里也把他的toString方法重写了:

public String toString() {
    return "游戏id:" + id + ", 用户名: = " + username + ", 密码: = " + password + ", 游戏图片: = " + path + ", 进度: = " + arrToString();
}

public String arrToString(){
    StringJoiner sj = new StringJoiner(",","[","]");
    for (int i = 0; i < data.length; i++) {
        sj.add(data[i] + " ");
    }
    return sj.toString();
}

然后在测试类中定义一个用户对象:

int[] data = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
User u1 = new User(1,"张三","123qwe","girl11",data);

这个时候就要注意了,我们不能直接用,直接用他会报错,我们来看一下:

image.png

可以看到他报错了。那我们要用的时候也是需要重写:

@Override
protected Object clone() throws CloneNotSupportedException {
    // 调用父类中的clone方法
    // 相当于让java帮我们克隆一个对象,并把克隆之后的对象返回出去
    return super.clone();
}

到这里我们还要去实现一个Cloneable接口:

image.png Cloneable接口是什么意思呢?我们来看一下源码:

image.png

这里面是不是空的呀,是的。为什么是空的呢?我们来了解一下:

  • 如果一个接口里面没有抽象方法,表示当前的接口是一个标记性接口。
  • 现在Cloneable表示一旦实现,那么当前类的对象就可以被克隆。
  • 如果没有实现,当前类的对象就不能被克隆。

到这里我们就重写完了clone方法了,下面我们来克隆一下看看:

// 2.克隆对象。
User u2 = (User) u1.clone();

因为他帮我们创建出来的是User对象,所以还需要对他进行一个强转操作。我们下面来打印一下看看:

System.out.println("u1用户:" + u1);
System.out.println("u2用户:" + u2);

image.png

怎么样,是不是就克隆过来了呀!下面我们来说一下小细节:

  • 方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
  • 重写Object中的clone方法。
  • 让javabean类实现cloneable接口。
  • 创建原对象并调用clone就可以了。

到这里我们就学完啦,下面进行一个总结吧:

  • Object是Java中的顶级父类,所以的类都直接或间接的继承于Object类。
  • toString():一般会重写,打印对象属性值。
  • equals():比较对象时会重写,比较对象属性值是否相等。
  • clone():默认浅克隆。

objects

object:是一个工具类,提供了一些方法去完成一些功能。

成员方法

方法名说明
public static boolean equals(Object a,Object b)先做非空判断,比较两个对象
public static boolean isNull(Object obj)判断对象是否位null,为null返回true,反之
public static boolean nonNull(Object obj)判断对象是否为null,跟isNull的结果取反

我们来看个案例,我要判断两个学生属性值是否相同,我们以前是不是这样写的呀:

先来定义两个学生对象:

Student stu1 = null;
Student stu2 = new Student("张三",20);

然后重写equals方法:

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

最后再写个判断的方法进行判断:

// 2. 比较两个对象的属性值是否相等
if(stu1 != null){
    boolean result = stu1.equals(stu2);
    System.out.println(result);
}else{
    System.out.println("调用者为空!");
}

那是不是太麻烦啦,那有没有更简单的方法呢?其实是有的,我们来看一下利用Objects的成员方法有多方便吧:

equals

boolean result = Objects.equals(stu1, stu2);
System.out.println(result);

我们来运行看一下:

image.png

是不是true呀,这种写法是不是很简单方便呢?我们来看一下Objects的源码是怎么比较的吧:

image.png

  • 细节:
  • 1.方法的底层会先判断stu1是否为null,如果是null直接返回false。
  • 2.如果stu1不是null,那么就会利用stu1再次调用equals方法。
  • 3.此时stu1是Student类型,所以最终还是会调用Student中的equals方法。
    • 如果没有重写就比较地址值。如果重写了就比较属性值。

isNull

判断对象是否为null,为null返回true,反之

Student stu3 = new Student();
Student stu4 = null;
System.out.println(Objects.isNull(stu3));           // false
System.out.println(Objects.isNull(stu4));           // true

nonNull

判断对象是否为null,为null返回false,反之

Student stu3 = new Student();
Student stu4 = null;
System.out.println(Objects.nonNull(stu3));          // true
System.out.println(Objects.nonNull(stu4));          // false

到这里我们就学完啦,下面进行一个总结吧:

  • Objects是一个对象工具类,提供了一些操作对象的方法。
  • equals(对象1,对象2):先做非空判断,在比较两个对象
  • isNull(对象):判断对象是否为空
  • nonNull(对象):判断对象是否不是空

好啦,关于Object和Objects我们就学完啦,有什么不懂的可以一起在评论区互相讨论哟,我们下期不见不散!!!

==最后非常感谢您的阅读,也希望能得到您的反馈  ==