java 打印字符串示例的地址

oyt4ldly  于 2023-05-15  发布在  Java
关注(0)|答案(8)|浏览(158)
package com.testProject;
public class JavaSample {

    public static void main(String[] args) {

        String myString1 = new String("Sample1");
        System.out.println(myString1);
        String myString2 = new String("Sample2");
        System.out.println(myString2);
    }
}

在上面的代码中,如何打印我创建的“Sample1”和“Sample2”的这些String的地址,我需要打印String对象myString1和myString2的内存位置

xiozqbni

xiozqbni1#

看来你们都错了!我试着解释一下:

String s = new String("hi Mr. Buddy");
//        s = = "hi Mr. Buddy"; //is false
//        s.equals("hi Mr. Buddy"); //is true
        System.out.println( s.hashCode() );
        System.out.println( "hi Mr. Buddy".hashCode() );

        System.out.println( "hi Mr. Buddy" == s );

        System.out.println( "hi Mr. Buddy" );

在我的案例中的结果:

1372880496
1372880496
false
hi Mr. Buddy

正如我们所看到的,hashCode()是相同的,但是String有不同的地址(bcs“hi先生。Buddy”== s >>== false)?你觉得怎么样?
我发现:

System.out.println( "s=" + System.identityHashCode( s ) );
System.out.println( "..=" + System.identityHashCode( "hi Mr. Buddy" ) );

结果是:

s=733003674
..=1626549726
hpcdzsge

hpcdzsge2#

正如我的评论所指出的,这不是推荐的做法,但既然你问了...

private static Unsafe unsafe;

static
{
    try
    {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        unsafe = (Unsafe)field.get(null);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

public static long addressOf(Object o)
throws Exception
{
    Object[] array = new Object[] {o};

    long baseOffset = unsafe.arrayBaseOffset(Object[].class);
    int addressSize = unsafe.addressSize();
    long objectAddress;
    switch (addressSize)
    {
        case 4:
            objectAddress = unsafe.getInt(array, baseOffset);
            break;
        case 8:
            objectAddress = unsafe.getLong(array, baseOffset);
            break;
        default:
            throw new Error("unsupported address size: " + addressSize);
    }       

    return(objectAddress);
}
0ejtzxu1

0ejtzxu13#

内存地址通常不能通过Java语言获得,但是System.identityHashCode(myString1)可能足够接近,这取决于您要实现的目标。

e1xvtsh3

e1xvtsh34#

如果你的“地址”是这样的:

System.out.println(new Object());

java.lang.Object@31ec0130
你就可以

String s = new String("one");
System.out.println(Integer.toHexString(s.hashCode()));

1ae66
因为你认为的“地址”只是hashCode()转换成十六进制字符串。

旁注

这个答案在历史上被认为是正确的,并且只适用于没有覆盖hashCode()方法的类,但是**(如注解中所提到的)它不适用于String类**,因为它们覆盖了hashCode()方法。读者如果想了解关于这个问题的最新信息,应该首先浏览关于这个答案的所有评论/讨论,并参考更多的资源,或者引用这个问题和答案提出一个新的问题,并明确要求提供关于自撰写以来发生变化的事情的新信息。

ecr0jaav

ecr0jaav5#

我认为@AnNik的回答应该被认为是正确的答案。下面是比较。

String s1= "abc";
    String s2 = new String("abc");
    String s3= "abc";

    System.out.println(Integer.toHexString(s1.hashCode()));
    System.out.println(Integer.toHexString(s2.hashCode()));
    System.out.println(Integer.toHexString(s3.hashCode()));
    System.out.println(System.identityHashCode(s1));
    System.out.println(System.identityHashCode(s2));
    System.out.println(System.identityHashCode(s3));

输出:

17862
17862
17862
356573597
1735600054
356573597
q0qdq0h2

q0qdq0h26#

事实上你不能。JVM处理内存,gc可以在它认为合适的时候转移数据。
因此,在Java中并没有内存地址的“真实的”概念(它只是JVM所关心的)

m3eecexj

m3eecexj7#

为什么不使用printf和%B:

String s= new String("Hello");
System.out.println(Integer.toHexString(s.hashCode()));
System.out.printf("address of the reference variable s holding string \"%s\" is %h%n", s,s);
1sbrub3j

1sbrub3j8#

只需将你的字符串名称右移,后面跟着下面的代码:

string object.getClass.getName()+'@'+Integer.toHexString(string boject.hashCode());

例如:

String str=new String("Hello");
System.out.println(str.getClass.getName+'@'+Integer.toHexString(str.hashCode());

相关问题