进阶JAVA篇-Object类与Objects类、包装类的常用API(一)

目录

API

[1.0 API概念](#1.0 API概念)

[2.0 Object类的常用API](#2.0 Object类的常用API)

[2.1 Object 中的 tostring() 方法 表示返回对象的字符串表达形式](#2.1 Object 中的 tostring() 方法 表示返回对象的字符串表达形式)

[2.2 Object 中的 equals(Object o) 方法 ,判断两个对象的是否相等](#2.2 Object 中的 equals(Object o) 方法 ,判断两个对象的是否相等)

[2.2.1深入了解如何重写Object 中的 equals(Object o) 方法](#2.2.1深入了解如何重写Object 中的 equals(Object o) 方法)

[2.2.2 对重写Object 中的 equals(Object o) 方法再深入思考一下](#2.2.2 对重写Object 中的 equals(Object o) 方法再深入思考一下)

[2.3 Object 中的 clone() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象](#2.3 Object 中的 clone() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象)

2.3.1分析代码注意的地方

2.4对Object小结

[3.0 Objects类的常用API](#3.0 Objects类的常用API)

[3.1 Objects类中的 equals(Object a, Object b) 方法](#3.1 Objects类中的 equals(Object a, Object b) 方法)

[3.2 Objects类中的 isNull(Object obj) 方法](#3.2 Objects类中的 isNull(Object obj) 方法)

[3.3 Objects类中的 nonNull(Object obj) 方法](#3.3 Objects类中的 nonNull(Object obj) 方法)

[4.0 包装类概念](#4.0 包装类概念)

[4.1 Integer类中 valueOf(int i) 方法(其他基本数据对应的对象都大致相同,以Integer举例)](#4.1 Integer类中 valueOf(int i) 方法(其他基本数据对应的对象都大致相同,以Integer举例))

4.1.1自动装箱:

4.1.2自动拆箱:

4.1.3具体来应用:

[4.2 Integer类中 toString() 方法(其他基本数据对应的对象都大致相同,以Integer举例)](#4.2 Integer类中 toString() 方法(其他基本数据对应的对象都大致相同,以Integer举例))

[4.3 Integer类中 parseInt(String s) 方法(其他基本数据对应的对象都大致相同,以Integer举例)](#4.3 Integer类中 parseInt(String s) 方法(其他基本数据对应的对象都大致相同,以Integer举例))

[4.3.1对 parseXxx() 方法与 valueOf() 方法小结](#4.3.1对 parseXxx() 方法与 valueOf() 方法小结)


API

1.0 API概念

API中文名为:应用程序编程接口,就是JAVA已经帮我们写好了一些常用的程序,如方法、类等,我们直接拿来用就可以解决一些问题,这样就可以提高开发效率。

2.0 Object类的常用API

Object是所有类的祖宗类,因此,JAVA中所有类的对象都可以直接使用Object类中提供的一些方法。

2.1 Object 中的 tostring() 方法 表示返回对象的字符串表达形式

代码如下:

java 复制代码
public class API {

    public static void main(String[] args) {
        ToString t = new ToString();
        System.out.println(t.toString());
        //输出为:ToString@1b6d3586
        System.out.println(t);
        //输出为:ToString@1b6d3586
        
    }

}
class ToString {
    private String name;
    private int age;

    public ToString() {
    }

    public ToString(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;
    }
}

分析以上代码:第一个点,输出的代码为:ToString@1b6d3586 可以简单的理解为这就是代码一个对象的地址,地址以字符串的形式表达出来让我们来看。第二个点,用t.toString()与直接用 t 的效果是一样的,直接用变量名输出会默认调用该子类的父类Object中的toString方法。

一般来说,我们用这个toString()方法输出地址,对我们开发用处不大,所以可以去把这个方法进行重写,对这个重写后的toString()方法是得到对象中的内容。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args) {
        ToString t = new ToString("lisi",22);
        System.out.println(t.toString());
        //输出:ToString{name='lisi', age=22}
        System.out.println(t);
        //输出:ToString{name='lisi', age=22}

    }

}
class ToString {
    private String name;
    private int age;

    public ToString() {
    }

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

    //对toString()进行重写
    @Override
    public String toString() {
        return "ToString{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

运行结果如下:

分析以上代码:现在对象中内容是以字符串的形式输出,通过重写该方法,得到我们想到得到的内容了,所以toString()方法 存在的意义就是为了被子类重写,以便放回对象的具体内容。

2.2 Object 中的 equals(Object o) 方法 ,判断两个对象的是否相等

简单来说,就是判断两个对象的地址是否相等。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args) {
        Equals e1 = new Equals();
        Equals e2 = new Equals();
        Equals e3 = e2;


        System.out.println(e1.equals(e2));
        System.out.println(e1 == e2);

        System.out.println(e3.equals(e2));
        System.out.println(e3 == e2);
    }
}

class Equals {
    private String name;
    private int age;

    public Equals() {
    }

    public Equals(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;
    }
}

运行结果如下:

对以上代码分析:第一点,首先创建了两个对象,然后用Object 中的 equals(Object o) 方法 来进行两个对象比较,结果肯定是false(因为两个对象都是通过 new 对象的,地址肯定不一样的)。第二点,这个效果跟直接用 == 的效果是一摸一样的,都是通过比较地址是否相同。

所以对这个 equals(Object o)方法 是不满足我们的需求 ,就可以重写这个方法。一般来说,需要是要通过比较对象中的内容(比如名字,年龄)来判断两个对象是否相同。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args) {
        Equals e1 = new Equals("lisi",22);
        Equals e2 = new Equals("lisi",22);
        
        System.out.println(e1.equals(e2));
        System.out.println(e1 == e2);
    }
}

class Equals {
    private String name;
    private int age;

    public Equals() {
    }

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

    //重写 equals(Object o) 方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Equals equals = (Equals) o;
        return age == equals.age && Objects.equals(name, equals.name);
    }

    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;
    }
}

运行结果如下:

对以上代码进行分析:先通过有参数的构造器构建初识化的对象,然后调用重写 Object 中的 equals(Object o) 方法,从输出结果可以看出来,经过重写的方法,两个对象比较的不是对象的地址了,而是对象的具体内容。

2.2.1深入了解如何重写Object 中的 equals(Object o) 方法

代码如下:

java 复制代码
 //重写 equals(Object o)
    @Override
    public boolean equals(Object o) {
        //参数是Object,可以传进任何类型的对象
        if (this == o) return true;
        //判断如果是对象自己跟对象自己比较,那肯定一样哇,
        //就不用比较和后面的具体的内容了
        //所以这里比较的是地址,相同的地址肯定是自己本身啦
        if (o == null || getClass() != o.getClass()) return false;
        //判断传进来的对象是否是空的,如果是空的话就没有必要接着后续的比较了
        // 或者判断两个对象的类型是否相同,
        // 如果不相同就没有必要接着后续具体内容比较了,肯定是false。
        Equals equals = (Equals) o;
        //强制类型转化 变量名 o 传进来的类型是 Object,需要强制转化一下。
        return age == equals.age && Objects.equals(name, equals.name);
        //接下来就是进来对象中具体内容的比较了
    }
2.2.2 对重写Object 中的 equals(Object o) 方法再深入思考一下

第一点,getClass() 方法也是0bject 类的方法,值得注意的是为什么 既然传进来的是0bject 类型的 o 为啥判断的是Equals呢?

这是因为 getClass() 方法返回的是运行时类的引用,而不是编译时的类型。因此,如果一个对象是通过子类来创建的,那么getClass()方法返回的将是子类的Class对象,而不是父类的Class对象。

因此,getClass()方法的返回值类型是根据原始对象的运行时类型决定的,而不是根据引用类型决定的。

第二点,我们知道字符串String 类型已经重写了equals()方法,为啥要用这个Objects.equals(name, equals.name) 方法 不直接用String类中写好的equals()方法呢?这个下面介绍到 Objects 类会讲到的,具体的原因,接着往下看。

2.3 Object 中的 clone() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象。

具体使用代码如下:

java 复制代码
public class API {

    public static void main(String[] args)  throws CloneNotSupportedException{
        
        Clone clone = new Clone("lisi",22);
        Clone clone1 = (Clone)clone.clone();
    
        System.out.println(clone1.getAge());
        System.out.println(clone1.getName());
        System.out.println("--------------------");
        System.out.println(clone.getAge());
        System.out.println(clone1.getName());
    }
}
class Clone implements Cloneable{
    private String name;
    private int age;

    public Clone() {
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    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;
    }
}
2.3.1分析代码注意的地方:

1.重写的 clone () 的方法跟之前的有所区别,直接返回去调用父类的clone()方法,这是因为 父类的clone()方法被protected修饰,所以在为子类不同包下去访问,所以可以说这次的重写起到的作用是中介作用,或者起过度转移作用。

2.重写完 clone () 的方法 还需要再接入一个接口 implements Cloneable。(语法规定)

3.调用重写完之后的 clone () 的方法 返回的是Object 类型的对象,需要强制类型转换。

4.因为会报异常,需要加上 throws CloneNotSupportedException 这串代码。

2.4对Object小结

1.toString() 方法 基本作用:返回对象的字符串表达形式。存在的意义是,让子类重写,以便返回对象的内容。

2.equals() 方法 基本作用:比较两个对象的地址是否相同。存在的意义是,让子类重写,以便比较对象之间的具体的内容是否相同。

3.Object 中的 clone() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象。

3.0 Objects类的常用API

3.1 Objects类中的 equals(Object a, Object b) 方法

先做非空判断,再比较两个对象,属于类方法,由类直接调用,返回值是boolean类型。

java 复制代码
public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
        //先判断是否自己本身的对象与自己本身的对象进行对比,
        //或者检查a对象是否为 null 
        //最后再调用字符串String 类中的equals()方法
    }

回顾:Objects.equals(name, equals.name) 方法 不直接用String类中写好的equals()方法?

是因为Objects.equals(name, equals.name) 方法比直接使用String类中写好的equals()方法多做了一步,就是判断对象本身是否为null。简单来说,如果不使用Objects.equals(name, equals.name) 这个方法,直接用String类中写好的equals()方法 ,则对象本身是没有判断自己是否为null,而Objects.equals(name, equals.name) 方法补上了这个漏洞,进行对象与对象内容比较之前判断了对象本身是否为null。所以使用Objects.equals(name, equals.name) 方法会更加安全。

3.2 Objects类中的 isNull(Object obj) 方法

判断对象是否为null,如果是就返回true,若不是就false。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        IsNull isNull = null;
        IsNull isNull1 = new IsNull();
        System.out.println(Objects.isNull(isNull));
        System.out.println(Objects.isNull(isNull1));
    }
}
class IsNull {

}

3.3 Objects类中的 nonNull(Object obj) 方法

判断对象是否不为null,如果不为null就返回true,若为null就false。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        NonNull nonNull1 = null;
        NonNull nonNull2 = new NonNull();
        System.out.println(Objects.nonNull(nonNull1));
        System.out.println(Objects.nonNull(nonNull2));
    }
}
class NonNull {

}

4.0 包装类概念

在JAVA中,万物皆是对象,但是发现基本数据类型不是对象。此时包装类就可以将这些不是对象的基本数据类型包装成对象。而每个基本数据类型都会对应相应对象。

除了两个比较特殊,其他都很容易记住。

4.1 Integer类中 **valueOf(int i)**方法(其他基本数据对应的对象都大致相同,以Integer举例)

valueOf(int i) 方法就是将基本数据类 int 包装成对象。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        Integer integer = Integer.valueOf(12);
        System.out.println(integer);
    }
}
4.1.1自动装箱:

基本数据类型直接会自动装箱成对象。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        Integer integer = Integer.valueOf(12);
        System.out.println(integer);

        Integer integer1 = 13;
        System.out.println(integer1);
    }
}
4.1.2自动拆箱:

包装类型的对象会自动拆箱成基本数据类型。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        Integer integer = Integer.valueOf(12);
        System.out.println(integer);

        Integer integer1 = 13;
        System.out.println(integer1);

        Integer integer2 = 14;
        int i = integer2;
        System.out.println(i);
    }
}
4.1.3具体来应用:

我们知道泛型和集合是只能接受对象的,所以不能接受基本数据类型。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args){

        ArrayList<Integer> list = new ArrayList<>();
        list.add(12);//自动装箱

        int i = list.get(0);//自动拆箱
        System.out.println(i);


    }

4.2 Integer类中 toString() 方法(其他基本数据对应的对象都大致相同,以Integer举例)

可以将基本数据类型的数据转化为字符串。

代码如下:

java 复制代码
import java.util.ArrayList;
import java.util.Objects;

public class API {

    public static void main(String[] args){

        Integer integer = 12;
        String str = integer.toString();
        //这个用对象去调用toString()方法
        System.out.println(str+1);
        //输出结果为 121

        Integer integer1 = 13;
        String str2 = Integer.toString(integer1);
        //这个用类直接去调用toString()方法
        //这里的参数既可以直接写13,也可以integer1变量,因为自动拆箱
        System.out.println(str2+1);
        //输出结果为 131

    }

4.3 Integer类中 parseInt(String s) 方法(其他基本数据对应的对象都大致相同,以Integer举例)

可以将字符串转化为基本数据类型。

代码如下:

java 复制代码
public class API {

    public static void main(String[] args) {

        String str = "23.23";

        int i = Integer.parseInt(str);
        //这个是类去调用方法,将字符串转化为对应的基本数据类型
        //需要注意如果用"23.23"类似这种,程序会报错
        int ii =  Integer.valueOf(str);
        //而这种是使用valueOf()方法将字符串转换为基本数据类型的包装类对象,
        // 然后再通过自动拆箱操作获取基本数据类型的值。
        System.out.println(i+1);
        System.out.println(ii+1);
        //输出 24

        String str2 = "23.23";
        double d = Double.parseDouble(str2);
        double dd = Double.valueOf(str2);

        System.out.println(d+1);
        System.out.println(dd+1);
        //输出24.23
    }

深入思考为什么可以用 valueOf() 方法将字符串转化为基本数据类型?上面讲到这个方法不是用来接收 int 数据类型,然后转化为包装类对象吗?

在valueOf() 方法参数中不只是只有 int 数据类型,也可以接收String类型,转化为 Integer 包装类。

所以这两中方法都可以将字符串转化为基本数据类型。

4.3.1对 parseXxx() 方法与 valueOf() 方法小结:

总结起来,可以通过parseXxx()方法将字符串转换为基本数据类型,或者通过valueOf()方法将字符串转换为基本数据类型的包装类对象,然后再通过自动拆箱操作获取基本数据类型的值。



相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端