API概述以及Object类的概述
1.API(Application Programming Interface):应用程序接口
2.JAVA API :就是JAVA提给我们使用的类,这些类将低层的实现封装了起来。
3.Object类概述:
类层次的根类,所有类都直接或间接的继承自该类
4.构造方法:public Object()
子类的构造方法默认是访问父类的无参构造
Object类的hashCode()方法
public int hashCode()
1.返回该对象的哈希码值,默认情况下,该方法会根据对象的地址来计算。
2.不同对象的hashCode()一般来说不会相同,但是同一个对象的hashCode()值肯定相同。
3.不是对象的实际地址值可以理解为逻辑地址值。
public static void main(String[] args) {
// Object:是所有类的顶层父类,所有的类就是直接或间接继承它
Object obj = new Object();
System.out.println(obj);
int i = obj.hashCode();
System.out.println(i);
Object obj2 = new Object();
System.out.println(obj2);
int i1 = obj2.hashCode();
System.out.println(i1);
// 不同对象的hash码值是不一样的
}
Object类的getClass()方法
public final Class getClass()
1.返回此Object的运行时类。
2.可以通过Class类中的一个方法,获取对象的真实类的全名称,public String getName()
public static void main(String[] args) {
Object obj = new Object();
// Object.java----Object.class----Object.class加载进内存时,
// 按照Java万物皆对象,它会把Object.class也看做一个对象,所以会创建字节码文件对象
// 我们可以通过getClass方法来获取字节码文件对象
Object obj2 = new Object();
//获取该类的字节码文件对象
Class<?> aClass = obj.getClass();
Class<?> aClass1 = obj2.getClass();
System.out.println(obj==obj2);//false
System.out.println(aClass==aClass1);//true,字节码文件对象只有一份
}
Object类的toString()方法
punlic String toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。将该类的所有的成员变量组成返回即可。
public static void main(String[] args) {
Object obj = new Object();
System.out.println(obj.toString());
Student student = new Student();
student.setName("wangwu");
student.setAge(23);
//System.out.println(student.getName());
//System.out.println(student.getAge());
System.out.println(student);
// 父类object类的toString()方法默认返回对象的地址值,但是有些子类觉得父类这个方法返回地址值意义不大
// 它想返回一些它觉得有用的东西,所以对toString()方法进行重写,返回它认为有意义的事情
// 比如想返回成员变量的值
}
Object类的equals()方法
1.指示其他某个对象是否与此对象“相等”。
2.默认情况下比较的是对象的引用是否相同。
public static void main(String[] args) {
Object obj = new Object();
Object obj2 = new Object();
//可以对比两个对象的地址值是否相同
System.out.println(obj == obj2);//false
boolean equals = obj.equals(obj2);
System.out.println(equals);//false
//也可以对比两个对象的地址值是否相同
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1 == s2);
boolean b = s1.equals(s2);
System.out.println(b);
}
3.由于比较对象的引用没有意义,一般建议重写该方法,一般用于比较成员变量的值是否相等。
4.==和equals的区别
public static void main(String[] args) {
//object类中的equals方法默认是在比较两个对象的地址值是否相同,有些子类认为比较地址值是否相同没有意义,
//所以有些子类就会重写equals方法,按照它自己的需求去比较
Student s1 = new Student("张三",21);
Student s2 = new Student("张三",21);
//我们自定义的类认为如果两个成员变量的值一模一样,就认为这两个对象是相同的
System.out.println(s1.equals(s2));
}
//重写equals方法
@Override
public boolean equals(Object obj) {//Object obj=s2
//如果不向下转型,Object中没有age,name,编译会报错
Student student=(Student) obj;
//"张三"=="张三",会比较两个字符串的地址值是否相同
//如果你要比较两个字符串字面上的内容是否相同,调用equals进行比较,String类重写了object类中的equals方法
return this.age==student.age&&this.name.equals(student.name);
}
Object类的equals()方法代码优化
1.提高效率
2.提高健壮性
@Override
public boolean equals(Object obj) {//Object obj=s2
//如果不向下转型,Object中没有age,name,编译会报错
// 如果传入着和调用者相同,直接返回true
if (this==obj){
return true;
}
// 健壮性: instanceof判断一个对象(引用)是不是该类型的对象(引用)
if (!(obj instanceof Student)){
return false;
}
Student student=(Student) obj;
//"张三"=="张三",会比较两个字符串的地址值是否相同
//如果你要比较两个字符串字面上的内容是否相同,调用equals进行比较,String类重写了object类中的equals方法
return this.age==student.age&&this.name.equals(student.name);
}
Object类的clone()方法
对象的克隆:深克隆和浅克隆。使用clone()方法采用的是浅克隆的方式。
clone()的权限修饰符是受保护的,再用的时候,让该类重写该方法,并把该类的权限修饰符改为public。
public static void main(String[] args) throws CloneNotSupportedException {
Dog dog = new Dog("小白",2);
System.out.println(dog);
Dog dog2 = (Dog) dog.clone();
System.out.println(dog2);
//1.你要调用clone()方法,首先你要重写父类的clone()方法,重写逻辑还是要调用父类的逻辑,把重写方法的权限修饰符改为public
//2.该类要实现Cloneable接口,不然就会抛出异常
}
}
//Cloneable是一个标记接口,里面没有任何抽象方法让你来实现,为了给类打一个标记,让JVM支持克隆
class Dog implements Cloneable{
String name ;
int age;
public Dog() {
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
对象浅克隆要注意的细节:
1.如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。
2.Cloneable接口只不过是一个标识接口而已,没有任何方法。
3.对象的浅克隆就是克隆一个对象的时候如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
4.对象的浅克隆也不会调用到构造方法的。
public static void main(String[] args) throws CloneNotSupportedException {
DogFood dogFood=new DogFood("王中王");
Dog dog = new Dog("小白",2,dogFood);
dog.dogFood.foodName="玉米肠";
System.out.println(dog.name);//小白
System.out.println(dog.age);//2
System.out.println(dog.dogFood.foodName);//金锣
Dog dog2 = (Dog) dog.clone();
dog2.name="小黑";
dog2.age=3;
dog2.dogFood.foodName="金锣";
System.out.println(dog2.name);//小黑
System.out.println(dog2.age);//3
System.out.println(dog2.dogFood.foodName);//金锣
}
static class Dog implements Cloneable{
String name;
int age;
DogFood dogFood;
public Dog() {
System.out.println("空参构造执行了");
}
public Dog(String name, int age, DogFood dogFood) {
System.out.println("有参构造执行了");
this.name = name;
this.age = age;
this.dogFood = dogFood;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class DogFood{
String foodName;
public DogFood() {
}
public DogFood(String foodName) {
this.foodName = foodName;
}
}
对象的深克隆(在IO流中学习):采用IO流来实现使用ObjectOutputStream将对象写入文件中,然后再用ObjectInputStream读取回来。