【问题标题】:Java String literals concatenationJava 字符串文字连接
【发布时间】:2013-05-22 04:32:10
【问题描述】:
    public static void main(String[] args){
        one();
        two();
        three();
    }

    public static void one() {
        String s1 = "hill5";
        String s2 = "hill" + 5;
        System.out.println(s1==s2);
    }

    public static void two() {
        String s1 = "hill5";
        int i =5;
        String s2 = "hill" + i;
        System.out.println(s1==s2);
    }

    public static void three() {
        String s1 = "hill5";
        String s2 = "hill" + s1.length();
        System.out.println(s1==s2);
    }

输出是

true 
false 
false 

字符串文字使用实习过程,那么为什么two()three()是假的。我可以理解three()two()不清楚。但需要对这两种情况进行适当的解释。

有人可以解释一下正确的理由吗?

【问题讨论】:

  • 阅读我问过的这个问题stackoverflow.com/questions/16729045/…
  • 为了好玩,你也可以试试twofinal int i = 5; 代替(它会打印true而不是false,因为现在i是一个常量)。
  • “每当有人将字符串与 == 开发人员进行比较时...”
  • 请注意,您永远不应该依赖== 来比较字符串——它会使您的程序变得脆弱。这只是一个字符串何时被保留的问题,这取决于使用的编译器(在one() 中)和使用的 JVM。
  • 是的,我只想知道概念。

标签: java string string-concatenation


【解决方案1】:

在 2 和 3 的情况下,编译器无法计算 String 的值,因为 hill + i 是运行时语句,s1.length() 也是如此

在这里阅读我问过同样的情况 - link

这样想 String s1 and s2 正在使用编译时常量 s1="hill5"s2="hill" + 5 ,记住,分配为文字的字符串是常量,它的状态不能修改,因为 字符串是不可变的.

所以在编译时,编译器会说“哦,是的,它们被计算为相同的值,我必须为 s1 和 s2 分配相同的引用”。

但是在two()three()方法的情况下,编译器说“我不知道,可能i的值可以随时更改,或者s1.length()随时更改”,它是运行时的事情,所以编译器不会将 two()three() 方法的 s2 放入池中,

因此,它们是错误的,因为在运行时,一旦正确更改就会创建新对象!

【讨论】:

  • 但是字符串文字是作为堆的一部分创建的,jvm检查字符串是否存在,如果不存在则创建新字符串,否则指向相同的位置..所以如果有两个和三个hill5字符串在游泳池里
  • @ankitagahoi 不是真的 - 只有常量字符串被放入池中,除非您使用 intern 方法...
  • 所有文字不进入池?
  • @ankitagahoi "hill" + i 不是字符串文字。 "hill5" 是……见:docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
  • @anshulkatta JVM 不检查任何此类事情。编译器将字符串文字放入常量池中:OP 的代码创建新字符串。你只是在编造它,即使在同样的陈述已经被更正之后。两次。规范性参考是 JLS 和 JVM 规范,而不是另一个论坛。
【解决方案2】:

带有编译时常量表达式的字符串将被放入字符串池中。主要条件是编译时常量表达式。如果您在方法two() 中将局部变量设为final,那么two() 也将打印true

public static void two() {
    String s1 = "hill5";
    final int i =5;
    String s2 = "hill" + i;
    System.out.println(s1==s2);
}

输出:

true

【讨论】:

    猜你喜欢
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2016-03-14
    • 2011-08-08
    • 2016-07-19
    • 1970-01-01
    相关资源
    最近更新 更多