问题概述
正常打印一个 Object 对象引用的时候,会默认打印 Object.toString() 方法返回的 getClass().getName() + "@" + Integer.toHexString(hashCode())
即打印出 对象所属类的名字与对象的 hashCode
StringCannotChange stringCannotChange = new StringCannotChange();
System.out.print(stringCannotChange);
com.practice.string.StringCannotChange@4554617c
但是当打印 String对象的引用时,则会显示字符串本身。
String str = "test string";
System.out.println(str);
test string
原因是 String 重写了 toString() 方法
Object.java 源码
String.java 源码
测试代码
package com.practice.string;
public class StringCannotChange {
public static void main(String[] args) {
// s 是对 常量存储区 中 "s" 的引用
String s = "s";
// s2 是对 常量存储区 中 "s" 的引用
String s2 = "s";
// s3(存储于内存的栈区,指向了新对象的首地址) 是对 一个新对象(存储于内存的堆区)的 引用
String s3 = new String("s");
// s4 也是一个对新对象的引用,但和 s3 分别指向不同的对象
String s4 = new String("s");
System.out.println(s == s2); // true
System.out.println(s3 == s2); // false
System.out.println(s3 == s4); // false
System.out.println("------------------------------");
/*
* A String's hashCode() method is calculated based on the chars it contains.
* If two String objects contain the same chars with the same case and in the same order,
* then they will have the same hashCode().
* */
System.out.println(StringCannotChange.class.getName() + "@" + Integer.toHexString(s.hashCode()));
System.out.println(StringCannotChange.class.getName() + "@" + Integer.toHexString(s2.hashCode()));
System.out.println(StringCannotChange.class.getName() + "@" + Integer.toHexString(s3.hashCode()));
System.out.println(StringCannotChange.class.getName() + "@" + Integer.toHexString(s4.hashCode()));
System.out.println("------------------------------");
System.out.println(s.equals(s2)); // true
System.out.println(s.equals(s3)); // true
System.out.println(s.equals(s4)); // true
System.out.println("------------------------------");
StringCannotChange stringCannotChange = new StringCannotChange();
System.out.print(stringCannotChange);
System.out.println("------------------------------");
String str = "test string";
System.out.println(str);
System.out.println("------------------------------");
}
}
true
false
false
------------------------------
com.practice.string.StringCannotChange@73
com.practice.string.StringCannotChange@73
com.practice.string.StringCannotChange@73
com.practice.string.StringCannotChange@73
------------------------------
true
true
true
------------------------------
com.practice.string.StringCannotChange@4554617c------------------------------
test string
------------------------------
Process finished with exit code 0
Reference
https://stackoverflow.com/questions/21964606/java-string-pool-storage-doubts