Lines 3, 4 don't do the same thing, as:
String s1 = "Java"; may reuse an instance from the string constant pool if one is available, whereas new String("Java"); creates a new and referentially distinct instance of a String object.
Therefore, Lines 3 and 4 don't do the same thing.
Now, lets have a look at the following code:
String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // true
s2 = new String("Java");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
== on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. Usually, it is wrong to use == on reference types, and most of the time equals need to be used instead.
s1ands2are both references, certainly. Lines 3 and 4 don't do exactly the same thing. Normally a string literal like "Java" would be comparable with==for all other literals in a program. But callingnew Stringforces a new object and the two references are no longer equal with==.java.lang.String), which (under the hood) store object references. However, we normally just call these "objects", because Java does not let you work with the references "as references" - you only get the objects themselves whenever you interact with the variable. See e.g. javaranch.com/campfire/StoryPassBy.jsp.