解读java.lang包下Object类的API(一)

说明:

           object是类层次的根类,所有类的父(超)类

一、registerNatives()

private static native void registerNatives();

    static {

        registerNatives();

    }

     native表明一个java接口调用非java接口

     为了让JVM找到本地函数,以某种规则命名,将java方法注册到本地

     例如:java.lang.Object.registerNatives()对应(关联)本地函数C语言的Java_java_lang_Object_registerNatives方法

二、getClass()

public final native Class getClass();   

     返回该对象运行时的类的对象

     例如 定义一个类Person ,创建一个Person对象, Person p= new Person();

     此时调用p.getClass() 返回值即为Person类的对象即: Class c=p.getClass();

     可通过方法获取该类的名称等信息:c.getName() ,结果为"Person"

     此方法常用于反射

三、hashCode()

public native int hashCode();

     返回当前对象的哈希值 本地方法

     hashCode常规协定:

     在java应用执行期间,对同一对象多次调用haseCode方法,必须返回相同的整数(前提:equals比较时信息没有被修改)

      通过equals方法比较,两个对象相等,返回的值必须相同整数

      通过equals方法比较,两个对象不同,不一定生成不同的整数,但是不同对象生成不同的整数可以提高哈希表的性能

四、equals(Object obj)

public boolean equals(Object obj) {

        return (this == obj);

    }

     返回布尔值,表示其他对象是否与本对象相等

     参数:Object类型

     返回值:

     特点:

        自反性:对于任何非空引用值X,自己和自己比较即:X.equals(x),结果都为true

        对称性:对于任何非空引用值X和Y,当X.equals(Y)结果为true时,Y.equals(X)的结果一定为true

        传递性:对于任何非空引用值X、Y和Z,当X.equals(Y)结果为true,Y.equals(Z)的结果为true时,X.equals(Z)的值一定为true

        一致性:对于任何非空引用值X和Y,多次调用X.equals(Y)始终返回相同的值true或者false (前提equals对比的信息没有修改)

        对于任何非空引用值X,X.equals(null) 的结果都为false

     注意:

        Object中对于任何非空引用值X和Y,当且仅当X和Y指向同一对象时,返回值为true

        重写equals方法时建议要重写hashCode()方法以便维护haseCode的常规协定

五、clone()

protected native Object clone() throws CloneNotSupportedException;

     此方法为浅拷贝,本地方法

     返回值:返回当前对象的“副本”

     作用:需要获取到一个对象的拷贝用户某些处理,可以用此方法复制

     注意:

     浅拷贝:当对象中含有可变的引用类型属性时,复制得到的新对象对自己引用类型属性进行修改时,原始对象的引用类型属性也会跟着改变

            原因:复制时,对象的属性是基本类型是,对该字段进行复制,对象的属性是引用类型时,复制该字段的引用而不复制该引用指向的对象

          深拷贝:当对象中含有可变的引用类型属性时,复制得到的新对象对自己引用类型属性进行修改时,原始对象的引用类型属性不会跟着改变

                适用于引用类型变量比较少的情况

                需要自己改写,缺点:一个类当中有很多引用类型时,实现的代码比较复杂

          当引用类型变量较多时,建议使用序列化和反序列化实现

          使用clone()方法时,如果此对象的类不能实现Cloneable接口,会抛出CloneNotSupportedException

          由于Object类本身不实现Cloneable接口,所以对于Object对象调用clone方法会抛出异常

六、toString()

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

       返回值:对象的类名+@+对象的哈希码无符号十六进制表示,即对象的字符串表示形式

       解读:getClass().getName()

                调用本类方法可以不使用对象调用省略this. * 此处获取该对象所属的类名

       解读:Integer.toHexString(hashCode())

                表示此对象的哈希码无符号十六进制表示

      举例说明,传入的int=123456 * 1.toHexString(int i)

     1. public static String toHexString(int i) { return toUnsignedString0(i, 4); }

                参数:要转换成字符串的整数,此处传入的是对象的哈希码

     2.toUnsignedString0(i, 4); //此时toUnsignedString0(123456,4)

         private static String toUnsignedString0(int val, int shift) {

                    // assert shift > 0 && shift <=5 : "Illegal shift value";

                    int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val); //mag=32-Integer.numberOfLeadingZeros(123456)=32-15=17

                    int chars = Math.max(((mag + (shift - 1)) / shift), 1); //chars=Math.max(((17+(4-1))/4),1)=Math.max(5,1)=5

                    char[] buf = new char[chars]; //char[] buf =new char[chars]=new char[5]

                   formatUnsignedInt(val, shift, buf, 0, chars); //formatUnsingedInt(123456,4,buf,0,5)

                  // Use special constructor which takes over "buf".

                 return new String(buf, true); }

            私有方法:

                  参数:

                        val 表示传入的整数 此处传入的是对象的哈希码;

                        shift 表示进制4代表16进制

                       Integer.SIZE 为32

         3.Integer.numberOfLeadingZeros(int i) //即Integer.numberOfLeadingZeros(123456),执行结果返回n=15

             public static int numberOfLeadingZeros(int i) {

                      // HD, Figure 5-6

                     if (i == 0) return 32;

                     int n = 1;

                     if (i >>> 16 == 0) { n += 16; i <<= 16; }

                     if (i >>> 24 == 0) { n += 8; i <<= 8; }

                     if (i >>> 28 == 0) { n += 4; i <<= 4; }

                     if (i >>> 30 == 0) { n += 2; i <<= 2; }

                     n -= i >>> 31;

                     return n; }

         参数,i 表示传入整数,此处传入的是对象的哈希码 如果i的值为0,返回32 如果i不为零,返回i的二进制补码表示心事重最高位1位之前的零位数量

4.max(int a, int b)

         public static int max(int a, int b) { return (a >= b) ? a : b; } 参数:整数a和整数比 返回值:比较a和b,若a>=b,返回a;若a>>= shift;

 5.formatUnsignedInt(val, shift, buf, 0, chars);  //formatUnsingedInt(123456,4,buf,0,5)
        static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
                    int charPos = len;
                    int radix = 1 << shift; //表示2^shift 若shift=4 ,则表示2^4
                    int mask = radix - 1;
                    do {
                        buf[offset + --charPos] = Integer.digits[val & mask];//val & mask =val%(mask+1)
                        val >>>= shift;
                    } while (val != 0 && charPos > 0);
                    return charPos;
                    }
                其中Integer.digits[index] ,是一个集合,可通过index进行取数
                 final static char[] digits = {
                '0' , '1' , '2' , '3' , '4' , '5' ,
                '6' , '7' , '8' , '9' , 'a' , 'b' ,
                'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
                'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
                'o' , 'p' , 'q' , 'r' , 's' , 't' ,
                'u' , 'v' , 'w' , 'x' , 'y' , 'z'
            };
                formatUnsingedInt(123456,4,buf,0,5)
                第一次执行结果:charPos=5;radix=16;mask=15;buf[4]=Integer.digits[123456%(15+1)]=Integer.digits[0]=0;val==7716;charPos=4
                第二次执行结果:buf[3]=Integer.digits[7716%(15+1)]=Integer.digits[4]=4;val=482;charPos=3
                第三次执行结果:buf[2]=Integer.digits[482%16]=Integer.digits[2]=2;val=30;charPos=2
                第四次执行结果:buf[1]=Integer.digits[30%16]=Integer.digits[14]=e;val=1;charPos=1
                第五次执行结果:buf[0]=Integer.digits[1%16]=Integer.gigits[1]=1;val=0;charPos=0
                val=0停止运行buf={1,e,2,4,0}
    6.对于标题2中return new String(buf,true)的返回值为1e240
     7.对于整个方法返回值为String@1e240

你可能感兴趣的:(解读java.lang包下Object类的API(一))