java String对象对比问题

如图,输出和打印结果是什么?理由呢?图片

自己来回答吧,
为什么会有这个问题?
在出面试题的时候,考虑到==是比较的变量内存地址
固有str1==str2输出false
以下是想差了的
str3也是新的变量,地址应该也不同,str1==str3输出false

以下是正确理解
str3=“he”+“llo”在编译的时候虚拟机会做优化,会把str1,str3变量的地址优化为相同

哈哈 来晚了, str1==str3的时候,jvm是会优化的,不得不是jvm还是很机智的

都是输出false,因为字符串变量地址不一样,所以使用==的结果是不等,用 str1.equals(str2)才会返回true

==对比的是地址 equals对比的是字符串值

public class StringTest {
/**
* @param args
*/
public static void main(String[] args) {
String str1 = "hello";
String str2 = "he"+new String("llo");
String str3 = "he"+"llo";
String str4 = "hello";
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
System.out.println(str3.hashCode());
System.out.println(str4.hashCode());
System.out.println();
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str1==str4);
// 哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码.
// String类的hascode方法是根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串的内容相同,
// 返回的哈希码也相同。

// “==”判断2个变量的内存地址是否相同,1和2比较,2创建实例在堆内存中开辟了空间,比较地址不同,返回false。
// 1和3比较,3是拼接字符串,str3=“he”+“llo”在编译的时候虚拟机会做优化,会把str1,str3变量的地址优化为相同,返回为true
// 1和4都是在栈内存中比较是相等的。
}

分析的这么详细
不知道是不是真的
嘻嘻

好厉害的样子,貌似是这样的

false, true, true

图片说明
哈希本身就是一种算法,相同的字符串哈希的结果相同很正常
然而后面的四个结果~~是因为**字符串 常量池**的存在,如果字符串常量池中有该字符串,则直接返回该字符串的地址,没有才会创建新的字符串,一般情况下new出来的新的字符串的地址是新的地址

每次new出来的对象的hashCode都不同;String 的常量会进入到常量池;java有常量优化机制, 如果常量池里有了,就不需要再新建了

当Java程序直接使用“hello”时,JVM将使用常量池管理这些字符串;当时用new String("hello")时,JVM先使用常量池管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象保存在堆内存中。换句话说,new String("hello")一共产生了两个字符串对象

String s1 = "疯狂Java";
String s2 = "疯狂";
String s3 = "Java";
String s4 = "疯狂"+"Java";
String s5 = "疯"+"狂"+"Java";
String s6 = s2+s3;
String s7 = new String("疯狂Java");

    System.out.println(s1 == s4);//true
    System.out.println(s1 == s5);//true
    System.out.println(s1 == s6);//false
    System.out.println(s1 == s7);//false
  1. hashCode一样是因为String类重写了Object类的hashCode()方法,只要字符串相等,hashCode就是一样的
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;
    }

  1. 当Java程序直接使用“hello”时,JVM将使用常量池管理这些字符串;当时用new String("hello")时,JVM先使用常量池管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象保存在堆内存中。换句话说,new String("hello")一共产生了两个字符串对象
String s1 = "疯狂Java";
        String s2 = "疯狂";
        String s3 = "Java";
        String s4 = "疯狂"+"Java";
        String s5 = "疯"+"狂"+"Java";
        String s6 = s2+s3;
        String s7 = new String("疯狂Java");

        System.out.println(s1 == s4);//true
        System.out.println(s1 == s5);//true
        System.out.println(s1 == s6);//false
        System.out.println(s1 == s7);//false

String对象创建的理解,希望下面这个问答对你有帮助http://dashen100.com/question/1001