java基础-Object类及其重要方法

 

目录

1、getClass方法

2、equals方法

3、hashCode()方法

4、toString方法

5、clone方法

6、语法糖:自动装箱和拆箱


    Object类是所有Java类继承体系的根,所有java类包括数组都继承自Object类。Object类中共有12个方法,其中一个private的,两个是protected的,9个是public的.常用的方法列表如下:

方法

说明

Class getClass()

返回一个对象运行时的类class对象

int hashCode()

返回该对象的hash值

boolean equals(Object obj)

比较两对象是否相等

String toString()

返回该对象的字符串表示

Object clone()

实现对象的复制

   

 

1、getClass方法

        返回一个对象运行时的类class对象。一个类在加载进虚拟机时,会生成一个代表这个类的java.lang.Class对象,通过这个Class对象可以访问这个类在方法区中的各种数据。

    Object object = new Object();

    //返回当前对象对应类的Class对象
    System.out.println(object.getClass());//class java.lang.Object

    ObjectCase objectCase1 = new ObjectCase();
    System.out.println(objectCase1.getClass());//class com.study.basic.ObjectCase

    ObjectCase objectCase2 = new ObjectCase();
    System.out.println(objectCase2.getClass());//class com.study.basic.ObjectCase
    // 返回的都是ObjectCase的Class对象
    System.out.println(objectCase1.getClass()==objectCase2.getClass());//true
    
   System.out.println(objectCase1.getClass().equals(objectCase2.getClass()));//true
}

 

2、equals方法

equals方法比较的是两个对象是否相等。Object类中的实现如下,默认比较的是两个对象的地址。

public boolean equals(Object obj){
    return (this==obj);
}

 

一些类如Integer、String、Date都重写了equals方法。以比较两个对象的值来判断两个对象是否相等。String类中的equals方法实现如下:先比较是否是同一个对象,若不是同一个对象,再比较值是否相等。

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

注意:

  1. ==对于基本数据类型的变量比较的是他们的值是否相等。对于引用变量比较的是他们的内存地址。equals方法用于比较引用变量,默认实现是调用==比较内存地址,与==返回的结果相同,但对于一些重写了eqauls方法的类而言,equals方法与==方法返回的结果并不保证一致。
  2. 重写equals方法之后,必须重写hashCode方法,以保证eqauls相等的两个对象的hashCode相等。否则这个类无法和基于hash散列的集合一起正常运作,如HashMap、HashSet和HashTable.
  3. 重写equals方法必须要遵守equals方法的通用约定,否则依赖这些约定的类如集合类中的list、map等就可能会无法正常运作。(建议重写eqalus方法时仔细参考相关约定)
  • 自反性:对于任何非null的引用值x,需满足x.equals(x)返回true
  • 对称性:对于任何非null的引用值x、y,需满足x.equals(y)返回true时,y.equals(x)也必须返回true
  • 传递性:对于任何非null的引用值x、y、z,满足x.equals(y)返回true且y.equals(z)返回true时,x.equals(z)也必须返回true
  • 一致性:对于任何非null的引用值x、y,只要equals比较在对象中所用的信息没有被修改时,那么多次x.equals(y)会一致的返回true或一致的返回false
  • 非空性:对于任何非null的引用值x,x.equals(null)必须返回false

参考effectice java 第8条

 

3、hashCode()方法

hashCode方法返回的是对象的hash值,hash值在不同的JVM中默认实现是不同的,有些是返回的存储地址,但有些返回的是和存储地址相关联的值。

对于hashCode方法方法,使用时需要遵守Object类中对于hashCode方法的约定,javaSE规范中如下:

  • 在应用程序的执行期间,只要对象的equals方法的比较操作用到的信息没有被修改,那么对这个对象调用多次,hashCode方法每次都必须返回同一整数。在同一个应用程序的多次执行过程中,每次调用的返回的证书可能不一致
  • 如果两个对象根据equals方法比较是相等的,那么这两个对象的hashCode方法返回必须返回同样的整数
  • 如果两个对象根据equals方法比较是不相等的,那么这两个对象的hashCode方法不一定要产生同样的整数
static void hashCodeTest(){
    Object o1 = new Object();
    System.out.println(o1);
    System.out.println(o1.hashCode());
    System.out.println(Integer.toHexString(o1.hashCode()));

    //Integer 类重写了hashCode方法,并且生成的hash值就是Integer对象的基本值
    Integer i1 = 300;
    Integer i2 =300;
    System.out.println(i1.equals(i2));//true
    System.out.println(i1.hashCode());//300
    System.out.println(i2.hashCode());//300
    //String类也重写了hashCode方法,保证两个值相等的对象返回的hashCode值相等
    String s1 = "abc";
    String s2 = "abc";
    System.out.println(s1.equals(s2));//true
    System.out.println(s1.hashCode());//96354
    System.out.println(s2.hashCode());//96354
}

 

参考effectice java 第9条

 

4、toString方法

Object类默认实现的toString方法如下,返回的是类名+@+hash值

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

 

5、clone方法

clone方法是一个potected方法,表明对对象的克隆。

使用:由于clone方法是protected的,子类需要implements Cloneable接口,重写clone方法并且声明为public,才可被调用。示例:

public class People implements Cloneable{
    int a;
    ParentClass parentClass;

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
......
static void cloneTest(){
    People p1 = new People();
    p1.a=1;
    ParentClass parentClass = new ParentClass(3);
    p1.parentClass = parentClass;
    try{
        People p2 = (People) p1.clone();
        System.out.println(p1==p2);//false
        System.out.println(p1.equals(p2));//false
        System.out.println(p1.a==p2.a);//true
        System.out.println(p1.parentClass==p2.parentClass);//true
    }catch (Exception e){
    }
}    

注意:clone方法实现的是浅拷贝(生成一个新的对象,对象中的基本类型字段的值和源对象相同,引用字段与源对象指向的地址相同),若想实现深拷贝需要重写 clone 方法实现域对象的深度遍历式拷贝。

effective java 11条,阿里编程规约->编程规约->OOP 规约20条

 

6、语法糖:自动装箱和拆箱

基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱.

  • 进行 = 赋值操作(装箱或拆箱)
  • 进行+,-,*,/混合运算 (拆箱)
  • 进行>,<,==比较运算(拆箱)
  • 调用equals进行比较(装箱)
  • ArrayList,HashMap等集合类 添加基础类型数据时(装箱)
static void autoBox(){
    /**
     * 
     */
    // unbox 等价于 int a= new Integer(200).intValue();
    int a = new Integer(200);
    // box 等价于Integer b = Integer.valueOf(200);
    Integer b = 200;
    //auto unbox
    System.out.println(a+b);//400
    // unbox
    System.out.println(a==b);//true
    // unbox
    System.out.println(b==a);//true
    // box
    System.out.println(b.equals(a));//true

    //box 注:Integer.valueOf方法在-127~127范围内返回的是从缓存中取出的Integer对象,
    // 在这个范围之外返回的是新的对象。
    Integer aa =100;
    Integer bb =100;
    System.out.println(aa==bb);//true
    Integer aa1 =200;
    Integer bb1 =200;
    System.out.println(aa1==bb1);//false

}

 

 

 

你可能感兴趣的:(java)