目录
一、构造方法
只有无参构造方法
Object o =new Object();
二、常用方法
public String toString(); 返回对象的字符串表示形式
public boolean equals(Object obj); 比较两个对象是否相等
protected Object clone(int a); 对象克隆
1.toString:
代码:
Object obj=new Object();
String str1=obj.toString();
System.out.println(str1);//APIstudy.Object@14ae5a5
默认打印的是包名+类名+固定的@+地址值
实际上直接println效果也是一样的
System.out.println(obj);//APIstudy.Object@14ae5a5
因为Object是所有类的最高级父类 所以所有类都继承了Object的toString 方法 默认情况下直接println一个对象打印的就是地址值 但是地址值是没有意义的 我们想要看到对象内部的属性值 所以我们可以在子类中重写父类Object类中的toString方法
class students{
public students() {
}
public students(int age, String name) {
this.age = age;
this.name = name;
}
int age;
String name;
@Override
public String toString(){
return name+"的年龄为"+String.valueOf(age);
}
}
应用:
students xuesheng=new students(20,"朱伊成");
System.out.println(xuesheng.toString());
2.equals
比较的是地址值 如果想比较里面的属性 如toString里的students类的姓名和岁数 因为所有子类也都继承了最高父类object的equals的方法,所以直接重写,比较属性就可以.
3.clone
不能直接调用clone 他是protected树形 只能被本包中或其他包中的子类调用
所以必须重写clone方法
注:Cloneable接口
如果一个接口里没有抽象方法,表示当前的接口是一个标记性接口,现在Cloneable接口就表示一旦类实现,那么当前类的对象就可以被克隆,没有实现,那么当前类的对象就不能克隆。一定要注意不需要创建一个Cloneable接口文件!!!
代码实现:
package APIstudy;
import java.lang.CloneNotSupportedException;
public class Objectdemo {
public static void main(String args[])throws CloneNotSupportedException{
//先创建一个对象
int[]a= {1,2,3,4};
user u1=new user(10,"朱伊成","030611zyc",a);
//克隆
user u2=(user)u1.clone();
System.out.println(u2.getId()+u2.getUsername()+u2.getPassword());
}
}
class user implements Cloneable {
private int id;
private String username;
private String password;
private int[]date;
public user() {
}
public user(int id, String username, String password, int[] date) {
this.id = id;
this.username = username;
this.password = password;
this.date = date;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int[] getDate() {
return date;
}
public void setDate(int[] date) {
this.date = date;
}
@Override
protected Object clone()throws CloneNotSupportedException{
//调用父类中的clone方法 相当于让Java帮我们克隆
return super.clone();
}
}
注意:
①重写clone时 要throws出一个CloneNotSupportedException异常 CloneNotSupported异常需要import java.lang.CloneNotSupportedException.
②此时拷贝就有浅拷贝和深拷贝的区别
三、深拷贝和浅拷贝
浅拷贝:
我们重写的clone 代码中 就直接 用的是父类super的clone方法 ,但父类的clone本质上是拷贝地址值,也就是说拷贝出来的user2 的name id password属性和原本的user1指向的是同一个地址值,也就是说改变user2 或者 user1的属性,另一个也会跟着变 ,但注意,只有改变的属性是引用数据类型,才会跟着改变,因为引用数据类型的本质实质上存储的是另一个空间的地址值,而像int double这样的基本数据类型存储的是真实的值,一个改变了另一个拷贝对象不会跟着变。我们可以实践一下:
测试案例:
//先创建一个对象
int[]a= {1,2,3,4};
user u1=new user(10,"朱伊成","030611zyc",a);
//克隆
user u2=(user)u1.clone();
System.out.println(u2.getId()+u2.getUsername()+u2.getPassword());
u1.setId(25);
System.out.println(u2.getId()+u2.getUsername()+u2.getPassword());
System.out.println(u2.getDate()[0]);
a[0]=10;
System.out.println(u2.getDate()[0]);
user2的id没变 date数组变了
但是在我们拷贝对象的大多数时候都不想像浅拷贝一样 让不同的对象属性指向同一个地址 所以就要深拷贝 深拷贝就是重写clone的代码时的区别
深拷贝:
将引用数据类型都创建一个新的引用数据类型,此时这两个地址不一样,然后再将值一个一个拷贝,然后调用父类object的clone,然后调用setxx方法将new拷贝的个体的每一个引用数据类型都设置为新的。
代码:
@Override
protected Object clone()throws CloneNotSupportedException{
//调用父类中的clone方法 相当于让Java帮我们克隆
int[]date=this.date;
int[]newdate=new int[date.length];//创建一个新的数组 新数组和旧数组的地址不一样
for(int i=0;i<date.length;++i){
newdate[i]=date[i];//将每一个值拷贝
}
user u=(user)super.clone();
u.setDate(newdate);
return u;
}
案例测试:
//先创建一个对象
int[]a= {1,2,3,4};
user u1=new user(10,"朱伊成","030611zyc",a);
//克隆
user u2=(user)u1.clone();
System.out.println(u2.getId()+u2.getUsername()+u2.getPassword());
u1.setId(25);
System.out.println(u2.getId()+u2.getUsername()+u2.getPassword());
System.out.println(u2.getDate()[0]);
a[0]=10;
System.out.println(u2.getDate()[0]);
和浅克隆案例的区别就是 user2的date数组没有发生改变。
四、总结:
浅拷贝:不管对象内部的树形是基本数据类型还是引用数据类型,全部拷贝过来、
深拷贝:基本数据类型拷贝过来 字符串服用 引用数据类型重新创建
Object的克隆是浅克隆