2015-10-10 41 views
1

我想确认是否创建了两个字符串变量指向相同的内存。我的方式与普通类做了如何确认(或获取字符串的对象转义)如果字符串中创建的字符串?

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

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

输出

[email protected] [email protected] 

这里产生的输出是不准确的记忆地址,但它给了相同的十六进制代码,并且我可以说它们都指向相同的内存地址或值。

但在字符串的情况下

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

输出

helloworld helloworld 

其预期的输出,我知道a,b,c在池中创建的,因为他们是编译时间常数和ac做不指向相同的内存。但有没有什么办法可以得到像[email protected]这样的字符串的对象表示方式来获取该对象的十六进制代码来确认ac不指向相同的内存? 因为在创建字符串的情况下new String("helloworld")新内存分配给字符串。

我已经搜索过它,但dint找到类似于我的问题的任何东西。

在此先感谢。

回答

2

正如JLS

字面解释总是一个字符串,是指String类的同一个实例。

但是,它也取决于你如何形成String对象。
示例:调用new String("abcd")就像已经有字符串参数“abcd”,但仍强制JVM创建一个新的String引用。检查更多信息部分...

正如你在你的例子中说的,你不能得到指针ID,但你仍然可以通过调用toString()方法得到一些唯一的字符串,使用它符合它们的唯一类型。但是,的toString的实现Object.toString()

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

因此,它是的hashCode

根据Hashcode契约,如果两个对象相等,则表示它们的hashCode必须相同,但反之亦然。

的hashCode从spec常规协定是:

  • 只要它是一个 执行的Java应用程序在同一对象上多次调用,hashCode方法必须始终 返回相同的整数,如果没有使用等于 的对象的比较被修改。该整数不必保持 从应用程序的一次执行到同一应用程序的另一次执行 的一致。

  • 如果两个对象根据 equals(Object)方法相等,则对两个对象的每个对象调用hashCode方法必须产生相同的整数结果。

  • 不要求 ,如果两个对象根据 等号不相等(java.lang.Object)方法,则调用每个两个对象的 hashCode方法必须产生不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的 整数结果可能会提高散列表的性能。

所以,要么使用==运营商,这将使身份/参考检查或者必须信任JVM实现的字符串表达式总是指向唯一的参考,否则JVM没有遵守规范。


更多信息:

这是在上述JLS规范给出的例子。

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

产生输出:

真真真真

该实施例说明六个点:

  • 同一个包中相同类中的字符串表示对同一个String对象的引用。

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

  • 不同包中不同类中的文字字符串同样代表对同一个String对象的引用。

  • 由常量表达式计算出的字符串在编译时计算出来,然后视为它们是文字。

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

  • 明确实习计算的字符串的结果与任何具有相同内容的预先存在的文字字符串是相同的字符串。

+1

我很困惑,其答案选择,因为他们都是很好的,但我喜欢你的回答除了其他的是你hashCose javaspecs.Thanks – silentprogrammer

1

我想确认是否创建了两个字符串变量指向相同的内存

您可以检查任何对象引用在与==运营商相同的对象指向。这就是你需要:

boolean sameObject = (a == b); 

有没有什么方法可以让我得到像串串的对象表示@ 23122

是的,如果你真的想要的是:

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

但这不会有用,因为两个不同的对象可能具有相同的哈希码。散列码不一定是内存地址,并且usually isn't

+0

但'尽可能合理的实际,由类Object定义的hashCode方法确实返回不同对象的不同整数。' – EJP

+0

这是愚蠢的我我记得'=='参考检查:) – silentprogrammer

1

首先,你的方法是错误的。您正在计算没有从Object覆盖toString()方法的类的字符串表示形式。

Object.toString方法,如果不被重写时,返回一个由类,@的名称的字符串,并且对象的哈希码。这不是它的地址,它与地址无关。因此,具有相同散列码的两个对象将返回相同的字符串。

为了证明,让我们来看看它覆盖equalshashCode但不会覆盖toString方法的小类:

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

现在,让我们来试试你的区分两个不同的对象的方法:

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

印刷会是这样的结果:

[email protected] [email protected]

但很明显,int1int2指向两个不同的对象,用new明确创建!

因此,忘记这种方法 - 它没有意义。


现在,你怎么知道两个对象是不同的?很简单,请将参考文献与==!=进行比较。

所以,如果我尝试了上述

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

其结果将是true

这是相同的字符串:

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)); 

印刷的结果将是:

a refers to a different object than c? true 
b refers to a different object than d? false
相关问题