JAVA源码学习--String

来源:互联网 发布:c语言培训 编辑:程序博客网 时间:2024/05/17 06:49

最近发四重新学习java的基础,从基本类型以及里面的各种方法开始看起,看的一本书《JAVA核心技术卷1,基础知识》,这是第十版,讲的JDK8的一些特性。
我在想我们创建对象的时候都是这样进行创建的

People p = new People();Integer i = new Integer();

但是String 和基本类型可以这么写

int i = 1;String s = "ssss";//这种写法,不是新创建的对象是在常量池中存放了一个ssss的字符串,在栈里面,如果没有引用则消失

String 还可以这么写

String s = new String();//新建了一个String的对象,这个是创建了一个新的String的对象,在堆里面,不用的时候由垃圾回收器进行回收

这里需要注意堆和栈的区别

看到String源码里面有了个这个方法:

  public String(String original) {        this.value = original.value;        this.hash = original.hash;    }

这个构造方法作用是什么?构造方法传进来的参数的类型是他自己?
发现String这个类中有两个成员变量

 private final char value[];    /** Cache the hash code for the string */    private int hash; // Default to 0

其中第二个hash他描述的是hash值,表示的是什么意思?
下面是相应的方法

  /**     * Returns a hash code for this string. The hash code for a     * <code>String</code> object is computed as     * <blockquote><pre>     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]     * </pre></blockquote>     * using <code>int</code> arithmetic, where <code>s[i]</code> is the     * <i>i</i>th character of the string, <code>n</code> is the length of     * the string, and <code>^</code> indicates exponentiation.     * (The hash value of the empty string is zero.)     *     * @return  a hash code value for this object.     */    public int hashCode() {        int h = hash;        if (h == 0 && value.length > 0) {            char val[] = value;            for (int i = 0; i < value.length; i++) {                h = 31 * h + val[i];            }            hash = h;        }        return h;    }

方法好像是返回一个hase值,具体是什么意思还是不太明白
然后我们深入的看了一下,发现Object类里面也有一个方法

/**     * Returns a hash code value for the object. This method is     * supported for the benefit of hash tables such as those provided by     * {@link java.util.HashMap}.     * <p>     * The general contract of {@code hashCode} is:     * <ul>     * <li>Whenever it is invoked on the same object more than once during     *     an execution of a Java application, the {@code hashCode} method     *     must consistently return the same integer, provided no information     *     used in {@code equals} comparisons on the object is modified.     *     This integer need not remain consistent from one execution of an     *     application to another execution of the same application.     * <li>If two objects are equal according to the {@code equals(Object)}     *     method, then calling the {@code hashCode} method on each of     *     the two objects must produce the same integer result.     * <li>It is <em>not</em> required that if two objects are unequal     *     according to the {@link java.lang.Object#equals(java.lang.Object)}     *     method, then calling the {@code hashCode} method on each of the     *     two objects must produce distinct integer results.  However, the     *     programmer should be aware that producing distinct integer results     *     for unequal objects may improve the performance of hash tables.     * </ul>     * <p>     * As much as is reasonably practical, the hashCode method defined by     * class {@code Object} does return distinct integers for distinct     * objects. (This is typically implemented by converting the internal     * address of the object into an integer, but this implementation     * technique is not required by the     * Java<font size="-2"><sup>TM</sup></font> programming language.)     *     * @return  a hash code value for this object.     * @see     java.lang.Object#equals(java.lang.Object)     * @see     java.lang.System#identityHashCode     */    public native int hashCode();

里面对于这个方法的描述我也贴出来了,自己的英文不太好,看着百度翻译看的,对于里面的东西还是不太理解
Object是所有类的父类,所以String类里面重写了这个方法。
下面我们进行实验会发现一个有趣的现象

String string1 = "aaa";String string2 = new String(string1);String string3 = new String("aaa");System.out.println(string1==string2);//false 这个肯定是false,因为使用new时候是新建了一个String的对象,而string1是指向放在常量池中的一个地址(string2也是指向对象的一个地址)但是他们的haseCode是一致的System.out.println(string1.hashCode());System.out.println(string2.hashCode());System.out.println(string3.hashCode());//这三个个值是一样的/**但是如果是我们自己新建的实体类的话**/People p1 = new People();People p2 = new People();People p3 = p2;System.out.println(p1.hashCode());System.out.println(p2.hashCode());//这里的值是不一样的,为什么?System.out.println(p3.hashCode());//这里p3和p2的值是一样的

看一个文章说hashCode表示的是返回对象的地址值(不完全正确)
但是看Object这个类中的equals里面就是直接比较的地址的啊
我知道为啥String 的hashCode返回的是一样的了,因为他重写了hashCode这个方法(开始自己竟然没注意到。。)

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

hashCode不一样肯定不是同一个对象,但是hashCode一样的不一定是同一个对象

补充个意外的
JAVA创建对象的时候如果是基本的或者String数据类型需要放到常量池中,就会使用常量池中的属性而不是在堆中新开辟一个空间。
比如说People这个类中有int eye;那么如果people1 的eye=1;people2的eye =1;那么这两个都是使用栈中的一个地址的引用

0 0