String comparison in Java 6 vs Java 7 [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I know that Strings in Java should be compared using .equals() and not using == operator.
But in the given below code there is a primaryObserverId which has a value of ""
The given below if condition runs fine on Java 6 but fails on Java 7
String primaryObserverId = request.getParameter("primary_observer_id");
if(primaryObserverId == null || primaryObserverId=="")
primaryObserverId = RoleMap.getUserIdForThisSession(session.getId());
Need to know why this code was working on Java 6 and not on Java 7.
I know how the concept of String Pool works for string literals in java , just want to know the reason this abrupt behavior.
Can using different version of GlassFish may cause any issue as I am using GlassFish-2.1 with Java 6 and GlassFish-4.1 with Java 7

All string literals in java are placed in a special area of the heap as they are required. So if you have a variable that is initialised to an empty string, this string is added to the heap. If you have another variable that is initialised to an empty string then it will contain a reference to the empty string already on the heap rather than creating a new one. So it seems your problem is that when you run your application in java 6 for some reason an empty string is on the heap at that point so you can check that the two strings are exactly the same object. However when run in java 7 there is no empty string on the heap so the two string must be completely different objects.
See this article for a more complete explanation.

== compares the address in memory while equals() compares if 2 objects are meaningfully equivalent, so in your case it makes more sense to user the equals() method as the Servlet creates the String not using the pool, so they are not == but they are meaningfully equivalent, therefore equals.
String primaryObserverId = request.getParameter("primary_observer_id");
if(primaryObserverId == null || "".equals(primaryObserverId)){
primaryObserverId = RoleMap.getUserIdForThisSession(session.getId());
}

Related

How is this thing works internally? [duplicate]

This question already has answers here:
Comparing strings with == which are declared final in Java
(6 answers)
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
Please follow the code below:
String s="helloworld";
String ss="hello";
String sss=ss+"world";
System.out.print(sss==s);
The output is false. Don't they get checked with the string pool rule for String? And what if we make them final?
A little explanation of internal working will help. Thanks in Advance.
String literals points to the same location if the content of them is same, that's what I got from different sources, am I right? If yes, then what's happening here? I'm a little confused about it.
EDIT:-
I think I didn't phrase it correctly. Let me rephrase it a little(Sorry for earlier attempt):-
String ss="hello";
System.out.print(ss+"world"=="helloworld");
This returns false. However these are String literals and as I have read they don't create two different objects for same value. They are just reference to a same value. Here, "helloworld" is the value for both sides of ==. I hope that I'm able to communicate it well.
Because String is an object, it is comparing that the two objects are the same with ==, which will equate to false.
Using the object ss to concat into sss will not make s = sss.
If you set ss to s, then using == will equate to true since they are now the same object.
If you set a second String object with a string literal, using == will equate the true.
If you use the String object's function .equals(String), you will find that it equates to true.
If you compare two string literals, i.e. "helloworld" == "helloworld" or "helloworld" == "hello" + "world", these will also equate to true.
As lealceldeiro pointed out, strings should always be compared with .equals().
EDIT
A good thing to look at is this answer. It has good references and explanation.
Other resources:
JournalDev
Baeldung

Is string interning done at compile time in Java? [duplicate]

This question already has answers here:
When are Java Strings interned?
(2 answers)
Closed 7 years ago.
I am really confused with how string interning works in Java. When I write:
String a = "ABC";
String b = "ABC";
if (a==b)
System.out.println("Equal");
Does the compiler store the string literal "ABC" into the string constant pool at compile time?
That sounds illogical, because I thought the string constant pool was created by the JVM at runtime, and I don't see how that is possible if it is done at compile time since the Java compiler does not even invoke the JVM.
If it is not done at compile time and it is done at runtime then why does the following return false (taken from this answer)?
// But .substring() is invoked at runtime, generating distinct objects
"test" == "!test".substring(1) // --> false
If it is done at runtime then why can't the JVM figure out that they are the same string?
I am really confused as to how string interning works in Java and where exactly the Java string pool is stored.
The compiler puts the literal strings in the class file (and only unique ones, it consolidates all equivalent literals); the JVM loads those strings into the string pool when the class file is loaded.
If it is done at runtime then why can't the JVM figure out that they are the same String.
Because the string being returned by .substring has not been interned, and so is a different object than the equivalent "test" string in the string pool. If you interned it, you'd get true:
"test" == "!test".substring(1).intern() // true
Sections §4.4 of the JLS and §5.3 of the JVM spec look relevant.
Just to be clear: The correct way to compare strings in Java is to use the .equals method or similar, not ==. Using == with string instances is usually incorrect. (Unless you're playing with understanding when and how things are interned...)
I checked .class for
String a = "ABC";
String b = "ABC";
and found only one "ABC" in it. That is javac creates one constant of the same string at compile time.
But if 2 or more classes have the same "ABC" constant then JVM will place them at the same location in string pool

hashCode as object ref in JDK 8 [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
From what i know, jdk 8 now is assigning as hashCode the memory address of the object.
And, obj1 = obj2 returns true iff the obj1 is obj2, i.e., they're sitting at the same memory location.
However, the following code executes the "else" part-- not the "then" part of the if-stat which is what i expect:
String h1 = "heya";
String h2 = new String ("heya");
System.out.println("hashCodes "+h1.hashCode()+" "+h2.hashCode());
if (h1 == h2)
System.out.println("yeah - the same ");
else System.out.println("nope-- difft objects ");
What am i missing here?
TIA.
h1 and h2 are not sitting in the same memory location. You are calling a new String("heya") so the JVM will create a new instance of String. Therefore, h1 == h2 is false. The hasCode is the same because it is based on the char composing the String.
Using equals method instead of == will return true.
The String class overrides hashCode().

Why does Eclipse allow string comparisons with ==? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I understand and know why you typically have to use == to compare strings in java, but for some reason I am able to do it in Eclipse. My code is
Code:
public class Test{
public static void main(String [] args){
String str1 = "string";
if(str1 == "string"){
System.out.println("wtf");
}
}
}
Why does this print "wtf" yet using javac from command line does not?
Eclipse allows you to compare references because it is a legitimate comparison. Just probably not the one you really want.
Because of String interning it will sometimes appear to work, but you should not rely upon it unless you know the strings you're comparing have been interned. The correct way to compare Strings for equal value is to use .equals.
It allow cause it probably faster to compare two address than comparing 2 string (but use it with caution, you probably never have to compare two String address).
It is sometime usefull to compare Object memories address, and as long as String is an object, eclipse allow you to compare using ==

difference between string in java and j2me with respect to memory constraints? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the difference between strings allocated using new operator & without new operator in java J2ME?
Difference between
String str=new String("Thamilan");
and
String str="Thamilan";
in java and j2me,with respect to memory constraints.
You can calculate the memory allocation of string by following code
int NumOfBytes = 8 * (int) ((((no chars) * 2) + 45) / 8) ;
The first form creates a new String object each time you run it. The second form does not.
This applies to both Java SE and Java ME. Indeed, the basic representation of Java SE and Java ME strings is the same.
Using new String(...) is almost always unnecessary and wasteful. There is rarely any point having a new instance. All String objects are immutable in Java.
(There are rare situations where creating a new String is advisable. One is when you take a substring of a large String and that substring is likely to be reachable for much longer than the original one.)

Categories