Javase | Object类中常用方法

equals(object obj)方法 :

equals(object obj) 的含义
  • 默认的equals方法比较两个对象的引用的地址是否相等,不是比较具体的值,如要比较两个对象中的值/内容是否相等,此时要重写equals( )方法。
  • 然而,许多Java类(如StringInteger等)已经重写了equals( )方法,此时的equals( )比较的是两个对象的。
  • 在Java中,对象的引用是一个地址值,该地址指向该对象在内存中的位置。通过引用,我们可以访问和操作该对象。
equals(object obj) 源码
public boolean equals(Object obj) {
    
        
return (this == obj);
}
equals(object obj) 例子
public class Test() {
    
    

    //在普通的对象中时,equals()方法比较的是对象的引用(比较对象间的地址值)是否相等
    static class Student1 {
    
    
        String name = "张三";
        int age = 18;
    }

    static class Student2 {
    
    
        String name = "张三";
        int age = 18;
    }

    static class Student3 {
    
    
        String name = "李四";
    }


    public static void main(String[] args) {
    
    
        Object str1 = "Hello World";
        Object str2 = "Hello World2";
        Object str3 = str1;
        Object str4 = "Hello World";
		// 在String、Integer等时,equals()方法已被重写,此时比较的是对象的内容
        System.out.println(str1.equals(str2)); //false
        System.out.println(str1.equals(str3)); //true
        System.out.println(str1.equals(str4)); //true

        System.out.println("----------------------------");
        Student1 s1 = new Student1();
        Student2 s2 = new Student2();
        Student3 s3 = new Student3();
        //比较的是两个对象的引用(可理解为: 地址值),就算值相等,地址值一般也不会相等的
        System.out.println(s1.equals(s2)); // false 
        System.out.println(s1.equals(s3)); //false
        //要判断对象的内容是否相等,要重写equals()方法
    }
}
重写equals(object obj)方法

重写equals( )方法:判断对象的内容

public class Student {
    
      //重写equals()方法,通过该方法来判断两个对象的内容是否相等
    private String name;
    private int age;

    public Student(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
    
     //传入一个要判断的对象
        if (this == obj) {
    
     //如果两个对象引用相等,表明是同一个对象,对象的内容自然也相等
            return true;
        }

        //如果obj为null 或 两个对象的类都不同,那么对象的内容自然也是不相同
        if (obj == null || getClass() != obj.getClass()) {
    
    
            return false;
        }

        //将obj对象进行类型转换,然后进行对象的内容的判断
        Student student = (Student) obj;
        return age == student.age && Objects.equals(name, student.name);          	    	 	//Objects.equals()比较的是对象的内容
    }

      public static void main(String[] args) {
    
    
        Student student1 = new Student("张三",18);
        Student student2 = new Student("张三",20);
        Student student3 = new Student("张三",18);

        //如果用默认的equals()方法判断,那么这三个对象都不相等,重写后则 student1与 student3相等
        System.out.println(student1.equals(student2));  //false
        System.out.println(student1.equals(student3));  //true
    }
}

hashCode()方法 :

hashCode()的含义
  • 默认的hashCode()方法用于为对象生成一个整数表示的哈希码。
  • 对象的哈希码是通过哈希函数计算得出的。哈希函数通过会考虑对象的内部状态和内容,以便为不同的对象生成不同的哈希码。
  • 当我们需要使用哈希表数据结构(如HashMap、HashSet)等时。哈希表使用对象的哈希码来确定存储和查找的位置,通过合理的哈希码分布可以提高查找效率
  • 需要注意的是,不同的对象可能会返回相同的哈希值,这被称为哈希冲突
  • 在Java中,如果你重写了equals()方法,那么你也应该重写hashCode()方法,以保持它们的一致性。这是因为Java的规范要求相等的对象必须有相等的哈希值。
hashCode() 源码
  public native int hashCode();
hashCode() 例子
public class Test {
    
    

    public static class Student1 {
    
     

    }

    public static class Student2 {
    
    

    }
    
    public static void main(String[] args) {
    
    
        Student student = new Student();
        Student2 student2 = new Student2();

        //两个不通过的对象的哈希码是不一样的
        System.out.println(student.hashCode());  //668386784
        System.out.println(student2.hashCode()); //668386784
        //
        System.out.println(student.hashCode()==student2.hashCode()); // faslse

    }
}

为什么重写了equals()方法也要重写hashCode()方法呢?
  • 如果你重写了equals( )方法,那么你也应该重写``方法,以保持它们的一致性。这是因为Java的规范要求相等的对象必须有相等的哈希值。
  • 如果两个对象根据equals( )方法是相等的,那么它们的哈希码(由hashCode( )方法返回)应该相同。这是因为哈希码通常被用于在哈希表等数据结构中快速查找对象。如果相等的对象返回了不同的哈希码,那么可能会导致错误的行为
重写hashCode()方法
public class Person {
    
    
    private String name;
    private int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    //此处应重写equals()方法,但为节省代码量就不写了....,可看重写equals()篇

    @Override //根据对象的属性值计算出一个哈希码,以确保相等的对象具有相等的哈希码。
    public int hashCode() {
    
    
        // 定义一个常量prime,它是一个质数(通常选择一个质数可以保持哈希码的均匀分布)
        final int prime = 31;  
        int result = 1;  //result变量存储最终的哈希码
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    public static void main(String[] args) {
    
    
        Person person1 = new Person("张三", 20);
        Person person2 = new Person("张三", 20);

//上面两个对象如果重写了equals()方法,那返回值是true,此时也要重写hashCode()方法以确保两个对象的哈希码是一样的
        System.out.println(person1.hashCode()); // 776470
//两个对象的哈希码是一样的,这是重写了hashCode的功劳,也符合Java规则,因为重写了equals方法后对象一样,哈希码也要一样
        System.out.println(person2.hashCode()); //776470
    }
}

getClass()方法 :

getClass()的含义
  • getClass()用于返回对象的运行时类。
  • getClass()返回值是一个Class对象,可以使用该对象调用各种方法来获取有关类的信息。
getClass() 源码
@HotSpotIntrinsicCandidate
public final native Class<?> getClass();
getClass() 例子
public class Test {
    
    

    public static class MyClass {
    
    
        private int value;

        public MyClass(int value) {
    
    
            this.value = value;
        }
        

        //输出信息的方法
        public void printInfo() {
    
    
            System.out.println(value);
        }
    }

    public static void main(String[] args) throws
            NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    
    

        MyClass myClass1 = new MyClass(10);
        MyClass myClass2 = new MyClass(20);

        //获得类对应的Class类
        //使用 getClass()获得运行中的MyClass (获得Class类)
        Class<?> class1 = myClass1.getClass();
        Class<?> class2 = myClass2.getClass();
        //获得类名
        System.out.println(class1.getName());  // Test$MyClass
        System.out.println(class2.getName());  // Test$MyClass



        //获得方法对应的Method类
        Method printInfo_myClass1 = class1.getMethod("printInfo"); //返回一个Method类
        Method printInfo_myClass2 = class2.getMethod("printInfo");
        //调用类中方法
        // invoke()方法是Method类提供的一个方法,调用该类中的方法
        printInfo_myClass1.invoke(myClass1);    //方法输出: 10
        printInfo_myClass2.invoke(myClass2);   //方法输出: 20
        
    }
}

toString()方法 :

toString()的含义
  • 默认的toString( )方法用于将对象转换为字符串形式。
  • 在Java中,如果一个类没有重写toString()方法,那么该类的toString()方法将返回该类的类名和哈希码的十六进制字符串表示形式。如果我们想打印对象时返回的该对象中的内容,此时我们就需要重写toString( )方法。
  • 我们可以根据对象的属性值和需求来自定义的字符串的表示形式。
  • 例如,对于一个Person类,我们可以重写toString()方法来返回包含对象属性的字符串表示形式,如姓名和年龄。
toString() 源码
  • getClass().getName() : 获得运行时类的类名
  • Integer.toHexString : 用于将整数转换为十六进制的字符串
  • hashCode() : 为对象生成一个整数哈希码
  • Integer.toHexString(hashCode()); :哈希码的十六进制字符串表示形式
  • return getClass().getName() + “@” + Integer.toHexString(hashCode()); :
    返回一个包含对象类名和哈希码的十六进制字符串表示形式
public String toString() {
    
        
 return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

toString() 例子
public class Person {
    
    
    public static void main(String[] args) {
    
    
        
        Person person = new Person();
        //输出的默认的toString()方法的内容:  类名+@+哈希码的十六进制字符串表现形式
        System.out.println(person); //Person@16b98e56
    }


重写toString()方法
public class Person {
    
    
    private String name;
    private int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    public static void main(String[] args) {
    
    
        Person person = new Person("王五",21);
        System.out.println(person); // 打印的是: Person{name='王五', age=21}
        //如果不用重写toString方法,那打印的就是 类名+@+哈希码的十六进制字符串表示形式
    }
}

clone() 方法:

clone()的含义
  • clone( ): 创建并返回此对象的副本。
  • 要使用clone( )方法,它需要目标类必须实现cloneable接口。
  • 默认的clone()是浅拷贝,即复制对象时,新对象和原对象共享相同的内部对象引用。这意味着,对于引用类型的属性,副本和原对象将引用相同的对象实例。
clone() 源码
protected native Object clone() throws CloneNotSupportedException;
clone() 例子
public class MyClass implements Cloneable {
    
    
    private int id;
    private String name;

    public MyClass(int id, String name) {
    
    
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "MyClass{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) throws CloneNotSupportedException {
    
    
        MyClass class1 = new MyClass(1, "张三");
        MyClass class2 = (MyClass) class1.clone();
        System.out.println(class1); // MyClass{id=1, name='张三'}
        System.out.println(class2); // MyClass{id=1, name='张三'}
    }
}

猜你喜欢

转载自blog.csdn.net/m0_70720417/article/details/132156834