class TestStringLiteral {

    public static void main(String[] args) {
    
        /** char literal in String ************************************/
    
        String line = "A line with a carriage return \r";         
        
        System.out.println(line);
        System.out.println();        
        
        /** JLS 3.10.5 example ****************************************/
        // also see class other.Other.java
         String hello = "Hello";
         String lo = "lo";
        
         System.out.println("JLS 3.10.5 Example");
         System.out.println();
         System.out.println("\tString variables initialized as: ");
         System.out.println("\t String hello = \"Hello\" " );
         System.out.println("\t String    lo = \"lo\" ");
         System.out.println();
         System.out.println("\t hello == \"Hello\" \t\t" +
             (hello == "Hello"));
         System.out.println("\t Other.hello == hello \t\t" +
             (Other.hello == hello));
         System.out.println("\t other.Other.hello == hello \t" +
             (other.Other.hello == hello));             
         System.out.println("\t hello == (\"Hel\"+\"lo\") \t\t" +
             (hello == ("Hel"+"lo")));
         System.out.println("\t hello == (\"Hel\"+lo).intern() \t" + 
             (hello == ("Hel"+lo).intern() ));     
         System.out.println("\t hello == (\"Hel\" + lo) \t\t" +
             (hello == ("Hel"+lo)));                     
         System.out.println();
         
         /** Examples *************************************************/
                 
         String str1 = "Lions and Tigers and Bears!";
         String str2 = "Lions and Tigers and Bears!";
         String str3 = str2;
         String str4 = new String("Lions and Tigers and Bears!");
         String str5 = " Oh my!";
         String str6 = "Lions and Tigers and Bears! Oh my!";
         String str7 = str1 + str5;
         String str8 = (str1 +" Oh my!").intern();

         System.out.println("Further examples:");
         System.out.println("-----------------");
         System.out.println();                  
         // output is true as when str2 was created it used a string
         // literal that was already available in the String pool
         // JVM implicitly invokes intern() on string literals
         System.out.println("\t str1 == str2 \t -> " + (str1 == str2));
         
         // output is true as when str3 is computed at runtime 
         // it will hold the same reference value held by str2
         System.out.println("\t str1 == str3 \t -> " + (str1 == str3));
         
         // output is false as str4 was explicitly created as a new object
         System.out.println("\t str1 == str4  \t -> " + (str1 == str4));
         
         // output is true as str2 and str3 hold the same reference value
         System.out.println("\t str2 == str3 \t -> " + (str2 == str3));
         
         // output is false as str4 was explicitly created as a new object
         System.out.println("\t str2 == str4 \t -> " + (str2 == str4));
         System.out.println("\t str3 == str4 \t -> " + (str3 == str4));

         // output is false as str7 is newly created at runtime
         System.out.println("\t str6 == str7 \t -> " + (str6 == str7));
         
         // output is true as the intern() method was explicitly used
         // forcing a search for a match in the String pool
         System.out.println("\t str6 == str8 \t -> " + (str6 == str8));
    }    
}

class Other { static String hello = "Hello"; }
