Java Object类和Objects类

1.1 概述

Object类所在包是java.lang包。Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类;换句话说,该类所具备的方法,其他所有类都继承了。

1.2 常用方法

public String toString()				//返回该对象的字符串表示形式(可以看做是对象的内存地址值)
public boolean equals(Object obj)		//比较两个对象地址值是否相等;true表示相同,false表示不相同
protected Object clone()    			//对象克隆

案例1:演示toString方法
实现步骤:

  1. 创建一个学生类,提供两个成员变量(name , age);并且提供对应的无参构造方法和有参构造方法以及get/set方法
  2. 创建一个测试类(ObjectDemo01),在测试类的main方法中去创建学生对象,然后调用该对象的toString方法获取该对象的字符串表现形式,并将结果进行输出

如下所示:

public class Student {
	//学生类
    private String name ;       // 姓名
    private String age ;        // 年龄

    // 无参构造方法和有参构造方法以及get和set方法略
    ...
}
public class ObjectDemo01 {

    public static void main(String[] args) {

        // 创建学生对象
        Student s1 = new Student("itheima" , "14") ;

        // 调用toString方法获取s1对象的字符串表现形式
        String result1 = s1.toString();

        // 输出结果
        System.out.println("s1对象的字符串表现形式为:" + result1);

    }

}

运行程序进行测试,控制台输出结果如下所示:

s1对象的字符串表现形式为:com.itheima.api.system.demo04.Student@3f3afe78

为什么控制台输出的结果为:com.itheima.api.system.demo04.Student@3f3afe78; 此时我们可以查看一下Object类中toString方法的源码,如下所示:

public String toString() {		// Object类中toString方法的源码定义
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

其中getClass().getName()对应的结果就是:com.itheima.api.system.demo04.Student;Integer.toHexString(hashCode())对应的结果就是3f3afe78。
我们常常将"com.itheima.api.system.demo04.Student@3f3afe78"这一部分称之为对象的内存地址值。但是一般情况下获取对象的内存地址值没有太大的意义。获取对象的成员变量的字符串拼接形式才算有意义,怎么实现呢?此时我们就需要在Student类中重写Object的toString方法。格式为:

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

小结:

  1. 在通过输出语句输出一个对象时,默认调用的就是toString()方法
  2. 输出地址值一般没有意义,我们可以通过重写toString方法去输出对应的成员变量信息(快捷键:atl + insert , 空白处 右键 -> Generate -> 选择toString)
  3. toString方法的作用:以良好的格式,更方便的展示对象中的属性值
  4. 一般情况下Jdk所提供的类都会重写Object类中的toString方法

案例2:演示equals方法

public boolean equals(Object obj) {		// Object类中的equals方法的源码
    return (this == obj);
}

通过源码我们可以发现默认情况下equals方法比较的也是对象的地址值。比较内存地址值一般情况下是没有意义的,我们希望比较的是对象的属性,如果两个对象的属性相同,我们认为就是同一个对象;那么要比较对象的属性,我们就需要在JavaBean类中重写Object类中的equals方法。
小结:

  1. 默认情况下equals方法比较的是对象的地址值
  2. 比较对象的地址值是没有意义的,因此一般情况下我们都会重写Object类中的equals方法

案例3:对象克隆

把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制

对象克隆的分类:

深克隆和浅克隆

浅克隆:

​ 不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来 .基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。Object类默认的是浅克隆
在这里插入图片描述
深克隆:

​ 基本数据类型拷贝过来,字符串复用,引用数据类型会重新创建新的
在这里插入图片描述
代码实现:

public class ObjectDemo01 {
    public static void main(String[] args) throws CloneNotSupportedException {
        // protected object clone(int a) 对象克隆 

        //1.先创建一个对象
        int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
        User u1 = new User(1, "zhangsan", "1234qwer", "girl11", data);

        //2.克隆对象
        //细节:
        //方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
        //书写细节:
        //1.重写Object中的clone方法
        //2.让javabean类实现Cloneable接口
        //3.创建原对象并调用clone就可以了
        //User u2 =(User)u1.clone();

        //验证一件事情:Object中的克隆是浅克隆
        //想要进行深克隆,就需要重写clone方法并修改里面的方法体
        //int[] arr = u1.getData();
        //arr[0] = 100;

        //System.out.println(u1);
        //System.out.println(u2);

    }
}

import java.util.StringJoiner;
//Cloneable
//如果一个接口里面没有抽象方法
//表示当前的接口是一个标记性接口
//现在Cloneable表示一旦实现了,那么当前类的对象就可以被克降
//如果没有实现,当前类的对象就不能克隆
public class User implements Cloneable {
    private int id;
    private String username;
    private String password;
    private String path;
    private int[] data;

    public User() {
    }

    public User(int id, String username, String password, String path, int[] data) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.path = path;
        this.data = data;
    }

 //get set省略
    public String toString() {
        return "角色编号为:" + 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();
    }

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

        //先把被克隆对象中的数组获取出来
        int[] data = this.data;
        //创建新的数组
        int[] newData =new int[data.length];
        //拷贝数组中的数据
        for (int i = 0; i < data.length; i++) {
            newData[i] = data[i];
        }
        //调用父类中的方法克隆对象
            User u=(User)super.clone();
        //因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值
        u.data =newData;
        return u;
    }
}

2. Objects类

简介

Objects类所在包是在java.util包下,因此在使用的时候需要进行导包。并且Objects类是被final修饰的,因此该类不能被继承。Objects类提供了一些对象常见操作的方法。比如判断对象是否相等,判断对象是否为null等等。

常见方法

public static String toString(Object o) 					// 获取对象的字符串表现形式
public static boolean equals(Object a, Object b)			// 比较两个对象是否相等
public static boolean isNull(Object obj)					// 判断对象是否为null
public static boolean nonNull(Object obj)					// 判断对象是否不为null

案例演示
实现步骤:

  1. 创建一个学生类,提供两个成员变量(name , age);并且提供对应的无参构造方法和有参构造方法以及get/set方法,并且重写toString方法和equals方法
  2. 创建一个测试类(ObjectsDemo01), 在该类中编写测试代码

如下所示:

public class Student {

    private String name ;       // 姓名
    private String age ;        // 年龄

    // 其他代码略
    ...
        
}
public class ObjectsDemo01 {

    public static void main(String[] args) {

        // 调用方法
        method_04() ;

    }

    // 测试nonNull方法
    public static void method_04() {

        // 创建一个学生对象
        Student s1 = new Student("itheima" , "14") ;

        // 调用Objects类中的nonNull方法
        boolean result = Objects.nonNull(s1);

        // 输出结果
        System.out.println(result);

    }

    // 测试isNull方法
    public static void method_03() {

        // 创建一个学生对象
        Student s1 = new Student("itheima" , "14") ;

        // 调用Objects类中的isNull方法
        boolean result = Objects.isNull(s1);

        // 输出结果
        System.out.println(result);

    }

    // 测试equals方法
    public static void method_02() {

        // 创建两个学生对象
        Student s1 = new Student("itheima" , "14") ;
        Student s2 = new Student("itheima" , "14") ;

        // 调用Objects类中的equals方法,比较两个对象是否相等
        boolean result = Objects.equals(s1, s2);     // 如果Student没有重写Object类中的equals方法,此处比较的还是对象的地址值

        // 输出结果
        System.out.println(result);

    }

    // 测试toString方法
    public static void method_01() {

        // 创建一个学生对象
        Student s1 = new Student("itheima" , "14") ;

        // 调用Objects中的toString方法,获取s1对象的字符串表现形式
        String result = Objects.toString(s1);       // 如果Student没有重写Object类中的toString方法,此处还是返回的对象的地址值

        // 输出结果
        System.out.println(result);

    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小钟不想敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值