欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【Java】 hashcode()和System.identityHashCode()

程序员文章站 2022-05-04 14:01:53
hashcode()和System.identityHashCode() openjdk8: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/5b86f66575b7 最近在看 源码的过程中看到这么一行 @{link org.springframewo ......

hashcode()和system.identityhashcode()

openjdk8: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/5b86f66575b7

最近在看spring源码的过程中看到这么一行

@{link org.springframework.context.support.abstractapplicationcontext}

public abstractapplicationcontext() {
        this.logger = logfactory.getlog(this.getclass());
        this.id = objectutils.identitytostring(this);
        this.displayname = objectutils.identitytostring(this);
        this.beanfactorypostprocessors = new arraylist();
        this.active = new atomicboolean();
        this.closed = new atomicboolean();
        this.startupshutdownmonitor = new object();
        this.applicationlisteners = new linkedhashset();
        this.resourcepatternresolver = this.getresourcepatternresolver();
}

在初始化context时设置 iddisplayname名字的时候 objectutils.identitytostring(this)

    public static string identitytostring(object obj) {
        return obj == null ? "" : obj.getclass().getname() + "@" + getidentityhexstring(obj);
    }

    public static string getidentityhexstring(object obj) {
        return integer.tohexstring(system.identityhashcode(obj));
    }

可以看到spring的做法是:类名 + @ + 16进制的字符串

所以system.identityhashcode()是什么?

hashcode()和system.identityhashcode()对比

来看个实例

public class ok {
    public static void main(string[] args) {
        ok ok1 = new ok();
        ok ok2 = new ok();

        system.out.println("ok1 - hashcode : " + ok1.hashcode());// ok1 - hashcode : 1554874502
        system.out.println("ok2 - hashcode : " + ok2.hashcode());// ok2 - hashcode : 1846274136


        system.out.println("ok1 - system.identityhashcode : " + system.identityhashcode(ok1)); //ok1 - system.identityhashcode : 1554874502
        system.out.println("ok2 - system.identityhashcode : " + system.identityhashcode(ok2));//ok2 - system.identityhashcode : 1846274136
    }
}

从结果上来看,相同对象的hashcode()和system.identityhashcode()是一致的

接下来,我们覆盖下hashcode()

public class ok {

    @override
    public int hashcode() {
        return 1;
    }

    public int getsuperhashcode(){
        return super.hashcode();
    }

    public static void main(string[] args) {
        ok ok1 = new ok();
        ok ok2 = new ok();

        system.out.println("ok1 - hashcode : " + ok1.hashcode()); // ok1 - hashcode : 1
        system.out.println("ok2 - hashcode : " + ok2.hashcode()); // ok2 - hashcode : 1


        system.out.println("ok1 - system.identityhashcode : " + system.identityhashcode(ok1));//ok1 - system.identityhashcode : 1554874502
        system.out.println("ok2 - system.identityhashcode : " + system.identityhashcode(ok2));//ok2 - system.identityhashcode : 1846274136

        system.out.println("ok1 - superhashcode : " + ok1.getsuperhashcode());//ok1 - superhashcode : 1554874502
        system.out.println("ok2 - superhashcode : " + ok2.getsuperhashcode());//ok2 - superhashcode : 1846274136


    }
}

可以看到,如果重载了hashcode()方法,而又想获未重载之前的object.hashcode(),则可以使用system.identityhashcode()

深入system.identityhashcode()

openjdk8: http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/5b86f66575b7

关于system.identityhashcode()里面的声明是这样的

 /**
     * returns the same hash code for the given object as
     * would be returned by the default method hashcode(),
     * whether or not the given object's class overrides
     * hashcode().
     * the hash code for the null reference is zero.
     *
     * @param x object for which the hashcode is to be calculated
     * @return  the hashcode
     * @since   jdk1.1
     */
    public static native int identityhashcode(object x);

对于源码中的解读可以参考 hashcode和identityhashcode底层是怎么生成的