2017-02-02 42 views
1
public static void main(String[] args) { 
     String[] arr = new String[5]; 
     for (int i = 0; i < arr.length; i++) { 
      arr[i] = "aaa" + i; 
     } 

    System.out.println(arr[0] == "aaa0"); // false 
    String s = "aaa0"; 
    System.out.println(s == arr[0]); // false 
    } 

我有一个关于该主题的几个问题可以帮助我了解字符串游泳池和的String []

  1. 什么是事实,从字符串字符串数组不会自动去刺背后登录池,不像字符串文字?

  2. 我是否正确理解只有字符串文字会隐式转到字符串池?

  3. 我是否正确理解从公共静态无效的主要该字符串数组(公共静态无效的主要(字串[] args))没有去字符串池中呢?

+2

这不是因为它在一个数组中。这是因为你正在动态地创建这些'String'('arr [i] =“aaa”+ i')。 – resueman

+2

@mstorkson虽然他正在谈论字符串池,所以这是必要的,以显示他的想法。 – Zircon

+1

@mstorkson在我的情况下,通过==比较来显示字符串池操作;通过equals(),一切都将是“真正的” - 字符串池中的字符串和外部字符串。 –

回答

3

编译器转换为循环下的封面!

生成的字节码将为每个循环迭代使用一个新的StringBuilder ...产生“新”创建的字符串对象!

含义;在“现实中,你的循环看起来‘更’像:

for (int i = 0; i < arr.length; i++) { 
    StringBuilder builder = new StringBuilder("aaa"); 
    builder.append(i); 
    arr[i] = builder.toString(); 
} 

(见here的理论背景)

这就是原因,使用==比较字符串有这样一个名声不好的。因为它往往会导致意想不到的结果。

而关于你的评论:点不是你正在使用的数组(其中:你应该不是被写入数组传递给主 - 你可以,但这是不好的做法)

+0

Thx为您的关注!那么public static void main(String [] args)呢? args字符串arr具有相同的逻辑?或者对于我的问题,编译器是一些例外情况? –

+0

非常欢迎。我做了一些更新,如果你喜欢我的回答,请考虑在某些时候接受;-) – GhostCat

2

您可以调用intern()方法强制进行字符串池化,即仅存储每个不同字符串值的一个副本。 检查了这一点:

public static void main(String[] args) { 
    String[] arr = new String[5]; 
    for (int i = 0; i < arr.length; i++) { 
     arr[i] = ("aaa" + i).intern(); 
    } 

    System.out.println(arr[0] == "aaa0"); 
    String s = "aaa0"; 
    System.out.println(s == arr[0]); 
} 
0

使用equals()如果你想比较内容两个对象的。这里有更多的解释

的“==”操作符的

在Java中,当“==”操作符用于比较两个对象,它 检查是否对象指记忆中的同一个地方。在 换句话说,它检查2个对象名是否基本上是 对同一内存位置的引用。

的equals()方法

Equals方法在对象类,从该每 类或者是直接或间接的后代来定义。默认情况下, equals()方法实际上与“==”运算符相同 - 这意味着它会检查两个对象是否引用内存中的相同位置。但是,equals方法实际上是为了比较两个对象的内容,而不是它们在内存中的位置。

System.out.println(arr[0].equals("aaa0")); // It give you True 
System.out.println(s == arr[0]); // It give you false