【问题标题】:printing the address of the string instances打印字符串实例的地址
【发布时间】:2013-04-27 10:08:58
【问题描述】:
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”这些字符串的地址,我需要打印字符串对象myString1和myString2的内存位置

【问题讨论】:

  • 我猜你不能在 Java 中做到这一点,没有指针。
  • 其实你可以看看我的回答,虽然它既不推荐也不简单,但是

标签: java string


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    实际上你不能。 JVM 处理内存,gc 可以在它认为合适的时候移动数据。

    所以在 Java 中没有“真正的”内存地址概念(它只是 JVM 的关注点)

    【讨论】:

      【解决方案3】:

      正如我的评论所指出的,不建议这样做,但既然你问了......

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

      【讨论】:

        【解决方案4】:

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

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

        java.lang.Object@31ec0130

        那么你就可以了,

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

        1ae66

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


        旁注
        这个答案在历史上被认为是正确的,并且只适用于没有覆盖 hashCode() 的类 方法,但 (如 cmets 中所述)不适用于 String,因为它们覆盖了hashCode() 方法。寻找最新消息的读者 关于这个问题的主题的信息应该首先通过所有 cmets/关于这个答案的讨论,应该进一步咨询 资源,或引用此问题和答案提出新问题和 明确要求有关已更改事物的新信息 自从他们被写出来。

        【讨论】:

        • 我认为哈希码与对象的实际内存地址无关。 :)
        • hashcode 是变量内容的数学计算值。无论如何它都不是地址。
        • @renz 这适用于任何没有覆盖 hashcode 方法并使用 Object 类的默认实现的类,该类在内存中打印地址。 String 类覆盖了 hashcode 方法,因此不返回 String 的内存位置。
        • 这是错误的,正如我上面的评论所说。拒绝我的投票
        • 这不是找到实际地址的方法。要检查它,请执行String s = "abc"; String s2 = new String("abc"); System.out.println(s1 == s2) 这将打印false,这意味着两个对象都不同。但是如果你进行操作,你会发现你得到的是“相同”的地址。
        【解决方案5】:

        只需正确你的字符串名称后跟此代码:

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

        示例:

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

        【讨论】:

          【解决方案6】:

          为什么不将 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);
          

          【讨论】:

            【解决方案7】:

            看来你们都是不正确的! 我试着解释一下:

                    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 Mr. Buddy" == s >>== false ) ?你觉得呢?

            我找到了:

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

            结果是:

            s=733003674
            ..=1626549726
            

            【讨论】:

            【解决方案8】:

            我认为@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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-03-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-29
              • 1970-01-01
              • 1970-01-01
              • 2013-10-02
              相关资源
              最近更新 更多