最近发四重新学习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
* String
object is computed as
*
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
*
* using int
arithmetic, where s[i]
is the
* ith character of the string, n
is the length of
* the string, and ^
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}.
*
* The general contract of {@code hashCode} is:
*
* - 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.
*
- 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.
*
- It is not 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.
*
*
* 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"-2">TM 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;那么这两个都是使用栈中的一个地址的引用