public static String toString(Object o) // 获取对象的字符串表现形式
public static boolean equals(Object a, Object b) // 比较两个对象是否相等
public static boolean isNull(Object obj) // 判断对象是否为null
public static boolean nonNull(Object obj) // 判断对象是否不为null
1.toString(获取对象的字符串表现形式)
默认情况下,因为object类中的toString方法返回的是地址值,所以默认打印地址值
如果我们要打印属性值,就必须重写toString方法
toString方法的结论
如果我们打印一个对象,想要看到属性值,那就必须重写toString方法
在重写的方法中,把对象的属性值进行拼接
public class objectdemo1 {public static void main(String[] args) {Student s1 = new Student();System.out.println(s1);//Object.Student@b4c966aString s2 = s1.toString();System.out.println(s2);//Object.Student@b4c966a//默认情况下,因为object类中的toString方法返回的是地址值,所以默认打印地址值//如果我们要打印属性值,就必须重写toString方法//toString方法的结论//如果我们打印一个对象,想要看到属性值,那就必须重写toString方法//在重写的方法中,把对象的属性值进行拼接}
}
重写之后
@Overridepublic String toString() {return name+","+age;}public class objectdemo1 {public static void main(String[] args) {Student s1 = new Student("zhangsan",18);System.out.println(s1);//zhangsan,18String s2 = s1.toString();System.out.println(s2);//zhangsan,18//默认情况下,因为object类中的toString方法返回的是地址值,所以默认打印地址值//如果我们要打印属性值,就必须重写toString方法//toString方法的结论//如果我们打印一个对象,想要看到属性值,那就必须重写toString方法//在重写的方法中,把对象的属性值进行拼接}
}
2.equals(比较两个对象是否相等)
默认比的是地址值,由于我们创建对象肯定创建出不同的对象,在堆区会开辟不同的内存空间,所以地址值肯定不一样,所以我们就要重写父类object里的equals方法
//public static boolean equals(Object a, Object b) 比较两个对象是否相等 public class objectdemo2 {public static void main(String[] args) {Student s1 = new Student();Student s2 = new Student();System.out.println(s1.equals(s2));//比的是地址值} }
结果
重新父类的equals方法
@Overridepublic 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);}
如果我们比较属性值:
//public static boolean equals(Object a, Object b) 比较两个对象是否相等
public class objectdemo2 {public static void main(String[] args) {Student s1 = new Student("张三",18);Student s2 = new Student("张三",18);System.out.println(s1.equals(s2));//比的是属性值}
}
结果
//public static boolean equals(Object a, Object b) 比较两个对象是否相等
public class objectdemo3 {public static void main(String[] args) {String s1 = "abc";StringBuffer sb = new StringBuffer("abc");System.out.println(s1.equals(sb));//false//因为equals方法是被s1调用的,而s1是字符串//所以equals要看String类中的//如果是字符串,则比较内部属性值//如果参数不是字符串,直接返回falseSystem.out.println(sb.equals(s1));//false//因为equals方法是被sb调用的,而sb是不是字符串是StringBuffer//所以equals要看StringBuffer类中的//因为StringBuffer没有重写equals方法,所以默认使用的是父类object类的equals方法//所以比较的是地址值//而这里s1和sb的地址值不一样,所以返回false}
}
结论:
3.浅克隆和深克隆
在Java中,实现浅克隆通常意味着你需要重写对象的clone()方法。Java中的Object类提供了一个默认的clone()方法,但这个默认实现是受保护的,因此你需要让你的类实现Cloneable接口(尽管这个接口是一个标记接口,没有任何方法),并且重写clone()方法以使其为public。
浅克隆
细节:
public class objectdemo5 {public static void main(String[] args) throws CloneNotSupportedException {Day day = new Day(2024, 6, 6);// 创建一个Animal对象Animal a = new Animal("小黑", 2, day);// 浅克隆这个Animal对象//先是object cloneA=a.clone();//然后强转成Animal类型// Animal cloneA=(Animal)a.clone();Animal cloneA = (Animal) a.clone();System.out.println(cloneA);}
}
package Object;import java.util.Objects;// 假设我们有一个简单的类Animal,它包含基本数据类型和另一个对象的引用
public class Animal implements Cloneable{private String name;private int age;private Day day; 假设Day是另一个类,并且我们想要浅克隆它public Animal(String name, int age, Day day) {this.name = name;this.age = age;this.day = day;}public Animal() {}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;}public Day getDay() {return day;}public void setDay(Day day) {this.day = day;}// 重写clone方法以实现浅克隆@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}// toString方法(可选,但有助于调试)@Overridepublic String toString() {return "Animal{" +"name='" + name + '\'' +", age=" + age +", day=" + day +'}';}
}
package Object;public class Day {private int year;private int month;private int day;public Day(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public Day() {}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}@Overridepublic String toString() {return "Day{" +"year=" + year +", month=" + month +", day=" + day +'}';}
}
结果:
clone 方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存,相对应的深拷贝则会连引用的对象也重新创建。
说白了 浅克隆 是克隆的对象和被克隆的对象共享一块内存,其实一方改变,则另一方也跟着改变
深克隆
深克隆我们可以导入第三方工具类
//用第三方工具//编写代码Gson gson = new Gson();//把对象变成字符串String s = gson.toJson(a);//克隆Animal a类//再把字符串变成对象即可Animal animal = gson.fromJson(s, Animal.class);//试一下是不是深克隆 animal没有变即深克隆day.setYear(2023);//打印对象System.out.println(animal);//拷贝之后的结果
结果
说白了 深克隆 是克隆的对象和被克隆的对象不是一块内存,其实一方改变,则另一方也不会跟着改变,克隆出来的本质是拷贝了一个副本,操作的是自己属于的那块内存
Objects
public static void main(String[] args) {Student s1 = null;Student s2 = new Student("zhangsan", 18);//判断对象是否为nullboolean result = Objects.equals(s1, s2);System.out.println(result);//false//细节://1.方法的底层会判断s1是否为null,如果为null,直接返回false//2.如果s1不为null,那就利用s1再次调用equals方法//3.此时s1是Student类型,所以最终还是会调用Student类型中的equals方法//如果没有重写,比较的是地址值,如果重写了,比较的就是属性值了
结果:
public static boolean isNull(Object obj) // 判断对象是否为null
public static boolean nonNull(Object obj) // 判断对象是否不为null
Student s3 = new Student("zhangsan", 18);Student s4 = null;System.out.println(Objects.isNull(s3)); 判断对象是否为null,为null返回trueSystem.out.println(Objects.isNull(s4));
结果:
// public static boolean nonNull(Object obj)// 判断对象是否不为nullStudent s5 = new Student("zhangsan", 18);Student s6 = null;System.out.println(Objects.nonNull(s5));//判断对象是否为不null,如果不为null返回trueSystem.out.println(Objects.nonNull(s6));
结果