解读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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 三重:代码、底层内存、源码 第一阶段:开发常用JavaSE基础、IDE、Maven、Gradle、SVN、Git、...
    guodd369阅读 16,450评论 1 44
  • 我想要的… 是义无反顾的"非你不可", 不是权衡得失后的牵强拉扯。 --1-- 夏天问我,人怎么可以变得这么快呢?...
    宋饭饭阅读 452评论 0 0
  • 2017年12月17日,2017年就剩下半个月了 俺连续一周熬夜,就是为了写年终总结,做总结屁屁踢,为自己的年终奖...
    壹本正经阅读 228评论 0 0