Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 字符串s=新字符串(“xyz”)。执行这行代码后,生成了多少个对象?_Java_Jvm - Fatal编程技术网

Java 字符串s=新字符串(“xyz”)。执行这行代码后,生成了多少个对象?

Java 字符串s=新字符串(“xyz”)。执行这行代码后,生成了多少个对象?,java,jvm,Java,Jvm,对于这个访谈问题,大家普遍同意的答案是代码创建了两个对象。但我不这么认为;我写了一些代码来确认 public class StringTest { public static void main(String[] args) { String s1 = "a"; String s2 = "a"; String s3 = new String("a"); System.out.println("s1: "+s1.hashCod

对于这个访谈问题,大家普遍同意的答案是代码创建了两个对象。但我不这么认为;我写了一些代码来确认

public class StringTest {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        String s3 = new String("a");
        System.out.println("s1: "+s1.hashCode());
        System.out.println("s2: "+s2.hashCode());
        System.out.println("s3: "+s3.hashCode());
    }
}
输出为:

这是否意味着只创建了一个对象

重申:我的问题是有多少对象是由以下代码创建的:

String s = new String("xyz")
class String_Check
{
    public static void main(String[] n)
    {
        String s1 = new String("abc");
        String s2 = "abc";
        String s3 = "abc";
        if (s1==s2)
            System.out.println("s1==s2");
        if(s1==s3)
            System.out.println("s1==s3");
        if(s2==s3)
            System.out.println("s2==s3");
    }
}
而不是
StringTest
代码

受@Don Branson的启发,我调试了以下代码:

public class test {
    public static void main(String[] args) {
        String s = new String("abc");
    }
}
结果是:


s的id是84,“abc”的id是82。这到底意味着什么?

根据编译器的智能程度,会创建2或3个对象

然而,您的测试是垃圾测试,因为
String
s的
hashCode
是基于
字符串的内容,而不是基于它们的身份。如果要检查标识,应使用
System.identityHashCode
或只进行
=
比较

只要有可能,编译器和运行时都可以(而不是强制)优化字符串创建。因此,他们优化了文本字符串,通过对现有的三个字符串使用单个文本。 无论如何,
new
操作符必须返回一个新对象(即新分配的对象)。
如果使用静态方法
String.valueOf
,则可以在运行时优化字符串。但我不知道当前JRE是否实际应用了任何缓存(检查哈希表可能比只分配一个新的
字符串要昂贵)

我在Eclipse调试器中运行了它。在该上下文中,将创建两个对象,一个id为17,另一个id为22:


仅仅因为所有哈希代码都相同,并不意味着您正在查看同一个对象。将创建两个对象。让我们来分析一下

String s = new String(“xyz”);
在“新字符串(“xyz”)部分中,将向新字符串“xyz”返回一个地址。当您说“String s=”时,这会将返回的地址分配给该对象,以便它们指向相同的位置,但新字符串和字符串s是两个独立的对象。

根据您使用的JVM/JRE,下面会出现错误。无论如何,最好不要担心这样的事情。有关任何更正/问题,请参见评论部分。 首先,这个问题实际上是关于这里所讨论的问题:

所以,这是每个人在这个问题上的指南

给定这行代码:
String s=新字符串(“xyz”)
有两种方式来看待这一点:

(1) 当代码行执行时会发生什么——它在程序中运行的文字时刻

(2) 语句创建了多少
对象
的净效果是什么

答复: 1) 执行此操作后,将创建一个附加对象。 a) 当JVM加载包含此行代码的
类时,将创建并插入
“xyz”
字符串

  • 如果某个
    “xyz”
    已从其他代码位于实习生池中,则该文本可能不会生成新的
    字符串
    对象
b) 创建新的
字符串s
时,内部
char[]
是插入的
“xyz”
字符串的副本

c) 这意味着,当执行行时,只会创建一个附加对象

事实上,
“xyz”
对象将在类加载后以及运行此代码部分之前创建

…下一个场景

2) 代码创建了三个对象(包括插入的
“a”
) a) s1和s2只是引用,而不是对象,它们指向内存中相同的
String

b) “a”是内部的,是一个复合对象:一个
char[]
对象和
String
对象本身。它由内存中的两个对象组成

c) s3,
新字符串(“a”)
生成一个以上的对象。新的
字符串(“a”)
不会复制“a”的
char[]
,它只在内部引用它。以下是方法签名:

public String2(String original) {
        this.value = original.value;
        this.hash = original.hash;
}

一个插入的
字符串
(“a”)
等于2个
对象
。一个
新字符串(“a”)
等于多个对象。代码的净效果是三个对象。

将为此创建两个对象:

String s = new String("abc");
一个在堆中,另一个在“字符串常量池”(SCP)中。引用
s
将始终指向
s
,并且SCP区域中不允许使用GC,因此在JVM关闭时,SCP上的所有对象都将自动销毁

例如:

在这里,通过使用堆对象引用,我们通过调用intern()获得相应的SCP对象引用


有两种方法可以在Java中创建字符串对象:

  • 使用新运算符,即

    String s1 = new String("abc");
    
  • 使用字符串文字,即

    String s2 = "abc";
    

  • 现在字符串分配在时间和内存上都很昂贵,所以JVM(Java虚拟机)执行一些任务。什么任务

    请参阅,无论何时使用
    new
    操作符,都会创建对象,并且JVM不会查看字符串池。它只是要创建对象,但是当您使用字符串文本创建字符串对象时,JVM将执行在字符串池中查找的任务

    也就是说,当你写作的时候

    String s2 = "abc";
    
    JVM将查看字符串池并检查“abc”是否已经存在。如果存在,则返回对已存在字符串“abc”的引用,并且不创建新对象;如果不存在,则创建对象

    那么你的情况呢 (a)

    • 由于使用了
      new
      ,因此创建了对象
    (b)

    • 使用字符串文字创建对象,并且“abc”不在 字符串池,从而创建对象
    (c)

    • 再次使用字符串文字和“abc”在t中
      String s2 = "abc";
      
      String s1 = new String("abc");
      
      String s2 = "abc";
      
      String s2 = "abc";
      
      class String_Check
      {
          public static void main(String[] n)
          {
              String s1 = new String("abc");
              String s2 = "abc";
              String s3 = "abc";
              if (s1==s2)
                  System.out.println("s1==s2");
              if(s1==s3)
                  System.out.println("s1==s3");
              if(s2==s3)
                  System.out.println("s2==s3");
          }
      }
      
      String s="
      
      Fred";
      System.out.println(s.hashCode());
      
      s=s+"47";
      System.out.println(s.hashCode());
      
      s=s.substring(2,5);
      System.out.println(s.hashCode());
      
      s=s.toUpperCase();
      System.out.println(s.hashCode());
      
      s=s.toString();
      System.out.println(s.hashCode());
      
      Fred--2198155         //1st object ----------------  String s="Fred"
      
      Fred47--2112428622    //2nd object ----------------  s=s+"47"
      
      ed4--100213           //3rd object ----------------  s=s.substring(2,5)
      
      ED4--68469            //4th object ----------------  s=s.toUpperCase()
      
      ED4--68469            //this is retrieved from the string constant pool -------- s=s.toString();
      
      String s="FRED";
      System.out.println(s.hashCode());
      
      s=s+"47";
      System.out.println(s.hashCode());
      
      s=s.substring(2,5);
      System.out.println(s.hashCode());
      
      s=s.toUpperCase();
      System.out.println(s.hashCode());
      
      s=s.toString();
      System.out.println(s.hashCode());
      
      FRED--2166379       //1st object ----------------  String s="Fred" 
      
      FRED47--2081891886  //2nd object ----------------  s=s+"47"
      
      ED4--68469          //3rd object ----------------  s=s.substring(2,5)
      
      ED4--68469          //this is retrieved from the string constant pool -------  s=s.toUpperCase()
      
      ED4--68469          //this is retrieved from the string constant pool -------- s=s.toString() 
      
              String s1="Pune";
              String s2="Mumbai";
              String s3="Pune";
              String s4=new String("Mumbai");
              System.out.println("S1 :"+s1.hashCode());  //S1 :2499228
              System.out.println("S2 :"+s2.hashCode());  //S2 :-1979126203
              System.out.println("S3 :"+s3.hashCode());  //S3 :2499228
              System.out.println("S4 :"+s4.hashCode());  //S4 :-1979126203
              System.out.println(s2==s4);     // false
      
      public class Rajesh {
          public static void main(String[] args){
              String s1=new String("Rajesh");
              System.out.println(s1+s1.intern());
          }
      }
      
      RajeshRajesh //s1=Rajesh+s2.intern()=Rajesh
      
      public String(String original) {
          int size = original.count;
          char[] originalValue = original.value;
          char[] v;
          if (originalValue.length > size) {
              // The array representing the String is bigger than the new
              // String itself.  Perhaps this constructor is being called
              // in order to trim the baggage, so make a copy of the array.
              int off = original.offset;
              v = Arrays.copyOfRange(originalValue, off, off+size);
          } else {
              // The array representing the String is the same
              // size as the String, so no point in making a copy.
              v = originalValue;
          }
          this.offset = 0;
          this.count = size;
          this.value = v;
      }
      
          String s1 = "abc";
          String s2 = "abc";
          String s3 = new String("abc");
          String s4 = s3.intern();
          System.out.println("s1: "+System.identityHashCode(s1));
          System.out.println("s2: "+System.identityHashCode(s2));
          System.out.println("s3: "+System.identityHashCode(s3));
          System.out.println("s4: "+System.identityHashCode(s4));
      
      String s1  ="Brajesh"; 
      String s = new String("Brajesh");//it will create only one object in heap area
      
      public static void main(String[] args)
      {
          String str = "atul";
          String string = new String("manoj");
          String string2 = "manoj";
          System.out.println(str == string);
      }
      
      **/** Cache the hash code for the string */
      private int hash; // Default to 0
      public int hashCode() {
          int h = hash;
          if (h == 0 && value.length > 0) {
              char val[] = value;
              for (int i = 0; i < value.length; i++) {
                  **h = 31 * h + val[i];**
              }
              hash = h;
          }
          return h;
      }**
      
      String s = new String("xyz");