目录
[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() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象)
[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.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() 方法 表示返回对象的字符串表达形式
代码如下:
javapublic 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()方法是得到对象中的内容。
代码如下:
javapublic 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) 方法 ,判断两个对象的是否相等
简单来说,就是判断两个对象的地址是否相等。
代码如下:
javapublic 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)方法 是不满足我们的需求 ,就可以重写这个方法。一般来说,需要是要通过比较对象中的内容(比如名字,年龄)来判断两个对象是否相同。
代码如下:
javapublic 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() 方法,当某个对象调用这个方法时,这个方法会返回一模一样的新对象。
具体使用代码如下:
javapublic 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类型。
javapublic 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。
代码如下:
javapublic 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。
代码如下:
javapublic 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 包装成对象。
代码如下:
javapublic class API { public static void main(String[] args){ Integer integer = Integer.valueOf(12); System.out.println(integer); } }
4.1.1自动装箱:
基本数据类型直接会自动装箱成对象。
代码如下:
javapublic 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自动拆箱:
包装类型的对象会自动拆箱成基本数据类型。
代码如下:
javapublic 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具体来应用:
我们知道泛型和集合是只能接受对象的,所以不能接受基本数据类型。
代码如下:
javapublic 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举例)
可以将基本数据类型的数据转化为字符串。
代码如下:
javaimport 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举例)
可以将字符串转化为基本数据类型。
代码如下:
javapublic 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()方法将字符串转换为基本数据类型的包装类对象,然后再通过自动拆箱操作获取基本数据类型的值。