How to confirm (or get the representation of an object in a string) if the string is created in the pool or not?

I want to confirm that the two String variables created are pointing to the same memory. How I did it with a regular class

Ideone a=new Ideone(); Ideone b=a; System.out.println(a+" "+b); 

Output

 Ideone@106d69c Ideone@106d69c 

The output shown here is not an exact memory address, but it gave a hex code, which is the same and with the help of which I can say that both of them point to the same address or memory values.

But in the case of String

 String a="helloworld"; String b="hello"; String c=b+"world"; System.out.println(a+" "+c); 

Output

 helloworld helloworld 

Its the expected output, and I know that a,b,c are created in the pool, because they are compile-time constants, and a and c do not point to the same memory. But is there any way I can get the representation of the string object as String@23122 to get the hex code of this object, to confirm that a and c do not point to the same memory? Because if you create a string using new String("helloworld") , new memory is allocated for memory.

I searched for it but did not find anything similar to my problem.

Thanks in advance.

+1
source share
3 answers

As explained in JLS

A string literal always refers to the same instance of the String class.

But also it depends on how you form the String object.
Example: Calling new String("abcd") already similar to the string parameter "abcd", but you still force the JVM to create a new reference to String. Read more ... Read more ...

As you said in your example, you cannot get the identifier of the pointer, but still you can get some unique string by calling the toString() method, using what it looks like they are unique. But the implementation of this toString Object.toString()

 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } 

So this is a HashCode .

According to the Hashcode contract, if two objects are equal, then this means that their hashCode must be the same, but it is not the other way around.

The general hashCode contract from spec :

  • Whenever it is called on the same object more than once during the execution of a Java application, the hashCode method must successively return the same integer if no information is used on equal object matching. This integer should not remain consistent with one execution of an application for another execution of the same application.

  • If two objects are equal according to equals (Object), then calls the hashCode method for each of the two objects must have the same integer result.

  • It is not required that if two objects are unequal according to equals (java.lang.Object), then calling the hashCode method on each of the two objects should produce different integer results. However, the programmer must be aware that integer results for unequal objects can improve the performance of the hash table.

So, either use the == operator, which will do the authentication / links, or you must trust the JVM implementation that String literals always point to a unique link, otherwise the JVM will not follow the specifications.


Additional Information:

This is an example given in the above JLS specification.

 package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); System.out.print((Other.hello == hello) + " "); System.out.print((other.Other.hello == hello) + " "); System.out.print((hello == ("Hel"+"lo")) + " "); System.out.print((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; } 

and compilation unit:

 package other; public class Other { public static String hello = "Hello"; } 

outputs the result:

true true true true false true

This example illustrates six points:

  • Literal strings of the same class in the same package represent references to the same String object.

  • Literal strings in different classes in the same package represent references to the same String object.

  • Literal strings in different classes in different packages also represent references to the same String object.

  • Lines computed by constant expressions are evaluated at compile time, and then processed as if they were literals.

  • Lines computed by concatenation at run time are created and therefore distinguished.

  • The result of explicitly interning the calculated string is the same string as any pre-existing literal string with the same contents.

+2
source

I want to confirm that the two created String lines point to the same memory

You can check if any object references point to one object using the == operator. This is all you need:

 boolean sameObject = (a == b); 

is there any way to get a representation of a string object like String @ 23122

Yes, if you really want this:

 System.out.println(a.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(a))); 

But this will not be useful, since two different objects can have the same hash code. A hash code is not necessarily a memory address, but is usually not .

+1
source

Firstly, your method is incorrect. You are counting on a string representation of classes that have not redefined the toString() method from Object .

The Object.toString method, if not overridden, returns a string consisting of the class name, @ and the hash code object. This is not his address; he has nothing to do with the address. Therefore, two objects with the same hash code will return the same string.

To demonstrate this, consider a small class that overrides equals and hashCode , but does not override the toString method:

 class MyInteger { int myInteger; public MyInteger(int myInteger) { this.myInteger = myInteger; } public int getInteger() { return myInteger; } @Override public boolean equals(Object obj) { if ( obj instanceof MyInteger ) { return myInteger == ((MyInteger)obj).myInteger; } return false; } @Override public int hashCode() { return myInteger; } } 

Now try your method of selecting two different objects:

 MyInteger int1 = new MyInteger(1004); MyInteger int2 = new MyInteger(1004); System.out.println(int1+" "+int2); 

The result will look something like this:

  MyInteger@3ec MyInteger@3ec 

But it is clear that int1 and int2 point to two different objects explicitly created with new !

So forget this method - it does not make sense.


Now, how do you know that two objects are different? Simple, compare links with == or != .

So if I tried above

 System.out.println( int1 != int2 ); 

The result will be true .

Same for strings:

 String a="helloworld"; String b="hello"; String c=b+"world"; String d="hello"; System.out.println("a refers to a different object than c? " + (a != c)); System.out.println("b refers to a different object than d? " + (b != d)); 

Printed Results:

  a refers to a different object than c?  true
 b refers to a different object than d?  false 
+1
source

Source: https://habr.com/ru/post/1234787/


All Articles