If you want want to compare the values of two Strings, then you have to use "str1.equals(str2)", not "==".
"==" actually compares whether the two variables are pointing to the same object.
In your first example, the compiler picks up that "Ja" and "va" are constants, and that therefore "Ja" + "va" is also constant. It therefore replaces "Ja" + "va" with a reference to "Java" in a constant-string pool - which happily happens to be the same object used to initialise str1.
In the second example, you have two separate String objects. In this case, the compiler cannot make the same constant assumptions, so the evaluation is left until runtime. This means a temporary result object will be created, which cannot be at the same address as the constant "Java" string.