目前我正在使用字符串操作,在进行演示时我发现了一些不同的行为。
以下是我的代码。
public class HelloWorld{
public static void main(String []args){
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
String strArray[] = {"Hello","Hello"};
String strArray1[] = new String[] {"Hello","Hello"};
System.out.println("str1==str2:: "+(str1==str2));
System.out.println("str1==str3:: "+(str1==str3));
System.out.println("strArray[0]==strArray[1]:: "+(strArray[0]==strArray[1]));
System.out.println("str1==strArray[1]:: "+(str1==strArray[1]));
System.out.println("strArray1[0]==strArray1[1]:: "+(strArray1[0]==strArray1[1]));
System.out.println("str1==strArray1[1]:: "+(str1==strArray1[1]));
System.out.println("args[0]==args[1]:: "+(args[0]==args[1]));
}
}
以上代码的输出是。我正在运行代码传递命令行参数。
java HelloWorld Hello Hello
str1 == str2 :: true
str1 == str3 :: false
strArray [0] == strArray [1] :: true
str1 == strArray [1] :: true
strArray1 [0] == strArray1 [1] :: true
str1 == strArray1 [1] :: true
args [0] == args [1] :: false
这里我有两个问题。
如果我比较String str1 == str3的引用,那么它将返回false,因为str3是使用 new String 创建的,因此不会驻留在String池中,那么 str1如何== strArray1 [1]返回true ??
strArray [0] == strArray [1]将返回true,strArray1 [0] == strArray1 [1]也返回true然后为什么命令行参数 args [0] == args [1 ]返回错误 ??
请指导。
答案 0 :(得分:4)
如果我比较String str1 == str3的引用,那么它将返回false 因为str3是使用新的String创建的,所以不会驻留在 字符串池,那么str1 == strArray1 [1]如何返回true ??
String strArray1[] = new String[] {"Hello","Hello"};
创建一个新的String数组,在数组*中引用相同的字符串 "hello"
。
strArray [0] == strArray [1]将返回true,strArray1 [0] == strArray1 [1] 也返回true然后为什么命令行参数args [0] == args [1] 返回假?
args[0]==args[1]
返回false
,因为它们是2个不同的实例(未添加到字符串池中),它们就像new String()
。
您可以使用以下方法轻松测试:
System.out.println(System.identityHashCode(args[0]));
System.out.println(System.identityHashCode(args[1]));
因此,传递给main()
的参数 NOT 被添加到字符串常量池。
答案 1 :(得分:3)
如果要比较的只是内容,请不要检查引用。这就是String
类首先提供equals()
方法的原因。前者测试参考平等,后者测试值平等。
内部处理字符串的方式在过去发生了变化,将来可能会发生变化。使用引用相等性依赖于您不应该真正依赖的实现细节。
封装的整个点是允许在不影响客户端代码的情况下更改内容。你应该遵循“规则”,这样你就不会被咬伤。
如果确实想要了解它是如何工作的,那么您应该阅读Java语言规范,here。这是语言的标准,任何未明确说明的内容都有一个与实施细节不相关的内容。