是否在池中创建字符串,如何确认(或获取字符串的对象表示)? [英] How to confirm( or get the object repesentation of string) if string created in pool or not?

查看:130
本文介绍了是否在池中创建字符串,如何确认(或获取字符串的对象表示)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确认创建的两个String变量是否指向相同的内存.我对普通类的处理方式

I want to confirm if two String variable created is pointing to the same memory.The way I did it with normal class

Ideone a=new Ideone();
Ideone b=a;

System.out.println(a+" "+b);

输出

Ideone@106d69c Ideone@106d69c

这里产生的输出不是确切的内存地址,但是给出的十六进制代码是相同的,通过它们我可以说它们都指向相同的内存地址或值.

The output produced here is not the exact memory address but it gave hex code which are same and by which I can say that they both are pointing to same memory address or values.

但是如果是String

But in case of String

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

输出

helloworld helloworld

它是预期的输出,我知道a,b,c是在池中创建的,因为它们是编译时常量,并且ac并不指向相同的内存.但是有什么办法吗?可以获取像String@23122这样的字符串的对象表示形式,以获取该对象的十六进制代码以确认ac不指向相同的内存吗? 因为在通过new String("helloworld")创建字符串的情况下,新的内存会分配给字符串.

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

我已经搜索过了,但发现没有任何与我的问题类似的东西.

I have searched it but dint find anything similar to my problem.

提前谢谢.

推荐答案

字符串文字始终引用String类的相同实例.

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

但是,这也取决于您如何形成String对象.
示例:调用new String("abcd")就像已经具有字符串参数"abcd"一样,但是仍然要强制JVM创建新的String引用.查看更多信息部分...

But also, it depends on how you form the String object too.
Example: Calling new String("abcd") is like having string parameter "abcd" already, but still you force JVM to create a new String reference. Check More Info section...

如您在示例中所说,您无法获取指针ID,但是仍然可以通过调用toString()方法来获得一些唯一的字符串,并使用它来证明它们是唯一的.但是该toString的实现是Object.toString()

As you said in your example, you cannot get the pointer id, but still you are able to get some unique string by calling toString() method, using that it kind of conforms they are unique. But the implementation of that toString is Object.toString()

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

因此,它是哈希码.

根据Hashcode合同,如果两个对象相等,则意味着它们的hashCode必须相同,但反之亦然.

As per the Hashcode contract, if two objects are equal, then that means their hashCode must be same, but it is not true vice versa.

来自的hashCode的常规协定规范是:

  • 在同一对象上多次调用同一对象时 执行Java应用程序时,hashCode方法必须一致 返回相同的整数,前提是不包含等于的信息 在对象上的比较被修改.该整数不必保留 从应用程序的一次执行到另一次执行的一致性 相同的应用程序.

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

如果两个对象根据 equals(Object)方法,然后在每个 两个对象必须产生相同的整数结果.

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

不是必需的 如果两个物体根据 equals(java.lang.Object)方法,然后在 两个对象中的每一个都必须产生不同的整数结果. 但是,程序员应该意识到, 不相等对象的整数结果可能会提高 哈希表.

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

因此,要么使用==运算符进行身份/引用检查,要么必须信任String文字始终指向唯一引用的JVM实现,否则JVM不遵循规范.

So, either use == operator which will make identity/reference check or you must trust the JVM implementation that the String literals always point to unique reference, else the JVM is not following the specs.

更多信息:

这是上面提到的JLS规范中给出的示例.

This is the example given in above mentioned JLS spec.

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"; }

和编译单元:

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

产生输出:

true是true true true false

此示例说明了六点:

  • 同一包中同一类中的文字字符串表示对同一String对象的引用.

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

同一包中不同类内的文字字符串表示对同一String对象的引用.

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

不同包中不同类内的文字字符串同样表示对同一String对象的引用.

Literal strings within different classes in different packages likewise represent references to the same String object.

由常量表达式计算的字符串是在编译时计算的,然后将其视为文字.

Strings computed by constant expressions are computed at compile time and then treated as if they were literals.

在运行时通过串联计算的字符串是新创建的,因此是不同的.

显式内联计算所得字符串的结果是与任何先前具有相同内容的文字字符串相同的字符串.

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

这篇关于是否在池中创建字符串,如何确认(或获取字符串的对象表示)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆