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);
    }

Output is

true 
false 
false 

String literals use interning process,then why two() and three() is false.I can understand in case of three() but two() is not clear.but need proper explanation for both cases.

Can someone please explain proper reason?

ankita gahoi
  • 1,532
  • 2
  • 15
  • 28

2 Answers2

14

In case of 2 and 3 , Compiler cannot calculate the value of String , since hill + i is a runtime statement , same for s1.length()

read here which i asked the same case - link

Think like this the String s1 and s2 are using compile time constant , s1="hill5" and s2="hill" + 5 , remember , string assigned as a literal is constant , its state cannot be modified , as String are immutable.

So at Compile time , compiler says "oh yeah , they are calculated as same value , i must assign the same reference to s1 and s2".

But in case of method two() and three() , compiler says " i dont know ,may be value of i can be changed any time , or s1.length() changes any time " , its a runtime thing , so compiler doesn't put s2 of two() and three() method in pool ,

Hence , they are false because at runtime , new object is created as soon it get changed right !!

Community
  • 1
  • 1
anshulkatta
  • 2,044
  • 22
  • 30
  • But String literals are created as part of heap and jvm check whether String exists or not,if not then it creates new String otherwise points to same location..so in case of two and three hill5 String is there in pool – ankita gahoi May 27 '13 at 10:39
  • 2
    @ankitagahoi Not really - only constant strings are put in the pool, unless you use the `intern` method... – assylias May 27 '13 at 10:39
  • all literals not goes to pool? – ankita gahoi May 27 '13 at 10:40
  • 1
    @ankitagahoi `"hill" + i` is not a String literal. `"hill5"` is... See: http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5 – assylias May 27 '13 at 10:42
  • so in case of two and three jvm will not check Strings in pool, it will create a new String ,am i right? – ankita gahoi May 27 '13 at 10:53
  • @ankitagahoi JVM will check that string s2 of two() and three() method is referring to new object so it will check reference that it does not refer to pool literal "hill5" – anshulkatta May 27 '13 at 10:56
  • hey before you go read this too , for scjp and correct clearance http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html – anshulkatta May 27 '13 at 10:59
  • 2
    @anshulkatta The JVM doesn't check any such thing. The compiler puts string literals in the constant pool: the OP's code creates new strings. You're just making it up, even after the same statement has already been corrected. Twice. The normative reference is the JLS and the JVM specification, not another forum. – user207421 May 27 '13 at 11:16
1

String with compile time constant expression will be put on String pool. The main condition is compile time constant expression. If you make local variable final in method two() then two() will also print true

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

Output:

true
Abu Yousuf
  • 5,729
  • 3
  • 31
  • 50