目录
- object
- objects
object
- 0bject是Java中的顶级父类。所有的类都直接或间接的继承于0biect类
- 0bject类中的方法可以被所有子类访问,所以我们要学习0bject类和其中的方法。
我们先来看一下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);
我们来运行看一下是什么效果:
我不是打印一个字符串嘛,怎么打印出了这串东西呀?其实这是一串地址值。我们来了解一下:
我们再来看一下toString的源码:
怎么样,是不是一样的呀。下面我们来了解一下细节吧:
- 细节:
- System:类名
- out:静态变量
- System.out:获取打印的对象
- println():方法
- 参数:表示打印的内容
那我们就想了,默认情况下因为object类中的toString方法返回的是地址值,那我想要看到对应的对象内部属性值怎么办呢?
如果父类的方法不能满足我们的需要,我们是不是可以重写他们的方法呀?
@Override
public String toString() {
return name + "," + age;
}
这个时候我们来运行看一下:
这个时候是不是就获取到属性的内部值了呀,由于我们没有给他赋值,所有打印出来的是默认值。我们来给他赋值再次运行看一下:
Student stu = new Student("张三",23);
这个时候就可以获取到属性的值啦。下面我们来总结一下:
- 如果我们打印一个对象,不想要看到地址值,而是看到属性值的话那么就重写toString方法就可以啦。
- 在重写方法中,把对象的属性进行拼接。例:
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
你们猜一下运行结果是多少呢?
是不是false呀,那是为什么呢?我们之前是不是知道了equals比较引用数据类型是比较地址值呀,而这两个对象又是new出来的,所以说地址值是不是不一样呀,所有返回的是false。
那我想比较两个对象的属性值怎么办呢?
父类不能满足我的需求,那我重写不就可以了吗。是的。其实这个重写方式不用我们自己写哟,可以按快捷键FN+ALT+INSERT:
选择equals(),然后一直Next下一步下一步就可以了。
到这里可以看到他把全部属性已经勾选上了,我们继续Next下一步。
@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));
来猜一下运行结果是多少呢?
两个都是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);
这个时候就要注意了,我们不能直接用,直接用他会报错,我们来看一下:
可以看到他报错了。那我们要用的时候也是需要重写:
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用父类中的clone方法
// 相当于让java帮我们克隆一个对象,并把克隆之后的对象返回出去
return super.clone();
}
到这里我们还要去实现一个Cloneable接口:
Cloneable接口是什么意思呢?我们来看一下源码:
这里面是不是空的呀,是的。为什么是空的呢?我们来了解一下:
- 如果一个接口里面没有抽象方法,表示当前的接口是一个标记性接口。
- 现在Cloneable表示一旦实现,那么当前类的对象就可以被克隆。
- 如果没有实现,当前类的对象就不能被克隆。
到这里我们就重写完了clone方法了,下面我们来克隆一下看看:
// 2.克隆对象。
User u2 = (User) u1.clone();
因为他帮我们创建出来的是User对象,所以还需要对他进行一个强转操作。我们下面来打印一下看看:
System.out.println("u1用户:" + u1);
System.out.println("u2用户:" + u2);
怎么样,是不是就克隆过来了呀!下面我们来说一下小细节:
- 方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
- 重写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);
我们来运行看一下:
是不是true呀,这种写法是不是很简单方便呢?我们来看一下Objects的源码是怎么比较的吧:
- 细节:
- 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我们就学完啦,有什么不懂的可以一起在评论区互相讨论哟,我们下期不见不散!!!
==最后非常感谢您的阅读,也希望能得到您的反馈 ==