Object
-
Object是Java中的顶级父类,所有的类都直接或间接地继承于Object类
-
Object类中的方法可以被所有子类访问,所以我们要学习Object类和其中的方法
Object的构造方法
| 方法名 | 说明 |
|---|---|
| public Object() | 空参构造 |
在继承中,子类中的共性才会被父类抽取,所以没有提供带参构造
Object的成员方法
| 方法名 | 说明 |
|---|---|
| public String toString() | 返回对象的字符串表示形式 |
| public boolean equals(Object obj) | 比较两个对象是否相等 |
| protected Object clone(int a) | 对象克隆 |
toString()
- 字符串表示形式:
java.lang.Object@7875765- 包名+类名 @ 对象地址值
- 细节:当使用println()方法直接打印对象时,获取的也是字符串表示形式
System.out.println();- System:类名
- out:底层定义的一个静态变量
public static final PrintStream out = null; - System.out:获取打印的对象
- println():方法
- 参数:打印的内容
- 核心逻辑:当我们打印一个对象时,底层会调用对象的toString方法,把对象变成字符串,然后再打印再控制台上,打印完毕换行处理
- 默认情况下,因为Object类中的toString方法返回的时地址值,所以再默认情况下,打印一个对象打印的就是地址值,但是地址值对我们来说时没什么意义的,我们更希望看到的是对象内部的属性值,这个时候就需要**重写父类Object类中的toString方法**
equals(Object obj)
- 在Object底层中的equals方法原理是
return this == obj;比较的是对象中的地址值,在对象的比较中意义不大,所以需要在子类中重写equals方法满足需求
String s = "abc";
StringBuilder sb = new StringBuilder("abc");
System.out.println(s.equals(sb));//false
System.out.println(sb.equals(s));//false
s.equals(sb)- 对象s是String类,看String类中的equals方法
- String类中equals方法底层原理
- 先判断参数是否为String类
- 如果是String类,再比较内部的属性
- 但如果参数不是String类,直接返回false
sb.equals(s)- 对象sb是StringBuilder类,看StringBuilder类中的equals方法
- StringBuilder类继承于AbstractStringBuilder类,AbstractStringBuilder类默认继承于Object类
- 而StringBuilder类和AbstractStringBuilder类中都没提供equals方法
- 所以使用的是Object类中的equals方法,比较两个对象的地址值
clone(int a)
把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
-
无法直接调用clone方法
- clone方法被protected修饰,只能在同一个包中、同一个包中的其他类、不同包下的子类被访问,而无法在不同包下的无关类中被访问,clone方法定义在java.lang包下
- 因此想要使用clone方法只能自己去重写
-
使用方式
- 重写Object类中的clone方法
@override protected Object clone() throws CloneNotSupportedException { //调用父类中的clone方法 //相当于让java帮我们克隆一个对象,并把克隆之后的对象返回出去 return super.clone(); }- 让Javabean类实现Cloneable接口
- 在Cloneable接口中没有抽象方法
- 如果一个接口里面没有抽象方法
- 表示当前接口是一个标记性接口
- 现在Cloneable表示一旦实现了,那么当前类的对象就可被克隆
- 如果没有实现,当前类的对象就不能克隆
public class User implements Cloneable { }- 创建原对象并调用clone方法
- Alt + Enter 选择第一个,让代码不要报错
- clone方法返回的是一个Object对象,需要手动进行类型强转
//方法会在底层帮我们创建一个对象,并把原对象中的数据拷贝过去 User u2 = (User)u1.clone();
浅克隆
- 不管对象内部的属性是基本数据类型还是引用数据类型,都拷贝过来
- Object中的克隆是浅克隆
深克隆
- 基本数据类型拷贝过来
- 字符串复用
- 引用数据类型会重新创建新的
- 深克隆在clone方法中的实现方式:自己重写clone方法
@override
protected Object clone() throws CloneNotSupportedException {
//先把被克隆对象中的数组取出来
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;
}
-
第三方工具类实现深克隆
- 第三方写的代码导入到项目中
- 当前模块下新建lib包
- 将gson.jar复制到lib包中
- 右键点击gson.jar,选择Add as library...,选择OK
- 编写代码
//创建对象 Gson gson = new Gson(); //把对象变成一个字符串 String s = gson.toJson(u1); //再把字符串变回对象 User user = gson.fromJson(s, User.claa); - 第三方写的代码导入到项目中
Objects
Objects是一个工具类,提供了一些方法去完成一些功能
Objects的成员方法
| 方法名 | 说明 |
|---|---|
| public static bolean equals(Object a, Object b) | 先做非空判断,比较两个对象 |
| public static boolean isNull(Object obj) | 判断对象是否为null,为null返回true,反之返回false |
| public static boolean nonNull(Object obj) | 判断对象是否为null,跟isNull的结果相反 |
- Objects.equals方法底层原理
- 先判断a和b是否为同一个对象,如果是,直接返回true
- 再判断a是否为null,如果为null,直接返回false
- 如果a不为null,那么就调用a中的equals方法
- 如果类中重写了equals方法,比较属性值
- 如果类中没有重写了equals方法,比较地址值
- 解决了本类中equals方法当调用对象本身为null时遇到的空指针异常错误
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
- Objects.isNull方法底层原理
public static boolean isNull(Object obj) {
return obj == null;
}
- Objects.nonNull方法底层原理
public static boolean nonNull(Object obj) {
return obj != null;
}