字符串s =新的String(“XYZ”)。多少对象后,这行代码执行已经取得?

问题描述 投票:22回答:19

共同约定回答这个面试问题是两个对象的代码创建的。但我不这么认为;我写了一些代码来确认。

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

取而代之的是StringTest代码。

通过@Don布兰森的启发,我调试下面的代码:

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

其结果是:

S的编号是84,和“ABC”的ID是82究竟是什么意思?

java jvm
19个回答
20
投票

有错误下DEPENDING在JVM / JRE大家使用。最好是不用担心这样的事情反正。看评论节的任何更正/关注。

首先,这个问题其实问这个地址在这里:Is String Literal Pool a collection of references to the String Object, Or a collection of Objects

所以,这是每个人都在这个问题上的指导。

...

Given this line of code: String s = new String(“xyz”)

还有的看着这两个方法:

(1)该行代码执行时会发生什么 - 它在程序运行字面的时刻?

(2)什么是多少Objects由语句创建的实际效果?

Answer:

1)本执行后,将创建一个附加的目的。

一)"xyz" String被创建并当JVM装载此行的代码被包含在class实习。

  • 如果"xyz"已经从一些其他的代码实习生池,则文本可能会产生没有新String对象。

B)当创建新String s,内部char[]是interned"xyz"字符串的一个副本。

C)这意味着,线执行时,仅存在一个创建的其他对象。

事实是"xyz"对象将被尽快创建为加载的类和该代码段中运行前。

......接下来的情景......

2)有由代码(包括实习"a"创建了三个对象)

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

一个)s1,s2的只是引用,而不是对象,并且它们指向相同String在存储器中。

b)在“a”被扣留,并且是复合对象:一个char[]对象和String对象本身。它包括内存中的两个对象。

c)中S3,new String("a")产生一个多个对象。新String("a")不会复制的“一”的char[],它只是引用它的内部。下面是该方法的签名:

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

一个实习String ("a")等于2 Objects。和一个new String("a")等于多了一个对象。从代码的净效果是三个对象。


0
投票

java.lang.String覆盖hashCode()方法使得该值依赖于字符串的内容。

其结果是,hashCode()不会告诉你实例的数量事情。它可以是相同的字符串,或者可以是与共享没有单一的字节另一个实例。同样关于equals()。这说明你的输出。

使用System.identityHashCode(..)对于这方面的研究。

may the source be with you


0
投票

@Giulio,你是对的。串S3 =新字符串( “ABC”);创建两个对象的一个​​与参考S3堆和另一个在SCP(无附图)。现在字符串s2 = “ABC”;在SCP不会创建任何新的对象,因为“ABC”已经存在的SCP。

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

A / P S1:366 712 642 S2:366 712 642 S3:1829164700,S4:366 712 642

由于我没有资格评论我在这里写的。


0
投票

如果我们在调试模式下运行日食下面的代码,我们会得到有多少对象与String string = new String("manoj");创建内部会造成String str = "manoj"in String类的构造函数的想法。在参考悬停后,只是检查ID如下图所示的屏幕截图。 ScreenShot

public static void main(String[] args)
{
    String str = "atul";
    String string = new String("manoj");
    String string2 = "manoj";
    System.out.println(str == string);
}

0
投票

有什么新的String(“<>”)后,到底会发生在被称为困惑,我发现这个线程。你的哈希码进行比较的理解是不是技术上是正确的,但。

INT hashCode()方法已被覆盖在String类,并将其返回取决于字符串文本的内容的值。

字符串S1 =新字符串( “你好”);字符串s2 =新字符串( “你好”);

所以s1.hashCode()= s2.hashCode()= anyStringOfContent_ “你好” .hashCode()

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

现在正好解释了为什么是这样做,实际上你可以阅读凯西塞拉利昂书里面有一个很好的解释为什么开发商这样做了(基本上返回true到equals()方法应该返回相同的hashCode()值的任何对象)。


-1
投票

我在Eclipse调试器中运行它。在这种情况下,创建了两个对象,一个与ID为17,其它的22:


-2
投票

有在Java中的一个概念叫做字符串池。一个字符串池(字符串实习生池)是Java堆了专门的存储区。当创建一个字符串,如果字符串中的池已存在,现有的字符串的引用将被退回,而不是创建一个新的对象,并返回其引用。

所以String s = new String(“xyz”)它会创建两个对象。

  1. 第一个对象将在Java永久堆内存被创建为我们传递参数的一部分 - “XYZ”。它会在字符串常量池中创建。
  2. 这将作为new操作者的一部分来创建 - 第二对象将Java堆存储器内被创建。

-2
投票

字符串s =新字符串( “XYZ”);

多少个对象已经在上面的代码中创建?

只有一个对象在上面的代码中创建,这就是在堆内存。

不是两个对象.....

如果创建了两个对象,一个是堆内存(新运营商),如果您的商店低于值使用字符串字面另一个是字符串常量池(字符串文字),

字符串S1 = “XYZ”;

它不会返回字符串常量池的对象S的参考。它会创建字符串常量池的为S1的新对象。

怎么样?

我们可以通过使用==运算符(S == S1)检查引用类型检查。如果s已经存储在字符串常量池的给它真正的,在这种情况下,输出是假的。

所以结论是一个对象在上面的代码中创建的。


-3
投票

仅仅因为你所有的哈希码相同并不意味着你正在寻找在同一个对象。创建了两个对象。让我们打破下来。

String s = new String(“xyz”);

在部分“新的String(‘XYZ’)”,地址返回到新的字符串“XYZ”。当你说“一个String =”,这是分配地址返回给该对象,使它们指向同一个地方,但新的字符串,字符串s是两个独立的对象。


-3
投票

我用hashcode()方法找到创建的字符串对象的数量。该方法hashcode()消化存储在参考变量成一个单一的散列值的数据。

情况1:

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

因此,4个对象共创建。

案例2:

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

3个对象总共创建。


-3
投票

有办法找到多少个对象正在使用的new关键字(String s1=new String("Rajesh"))创建的。

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

注:正如我们所知道的实习生方法总是打堆内存的字符串常量池。


8
投票

两个对象将为此创建:

String s = new String("abc");

一位在堆和其他在“字符串常量池”(SCP)。参考s将指向总是s,和GC没有在SCP面积允许,等等SCP的所有对象将在JVM关闭时自动销毁。

例如:

此处通过使用堆对象引用我们通过实习生的呼叫得到相应SCP对象引用()

String s1 = new String("abc");
String s2 = s1.intern(); // SCP object reference
System.out.println(s1==s2); // false
String s3 = "abc";
System.out.println(s2==s3); //True s3 reference to SCP object here

4
投票

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

  1. 使用new运算符,即 String s1 = new String("abc");
  2. 使用字符串文字,即 String s2 = "abc";

现在串分配是在时间和内存昂贵,因此JVM(Java虚拟机)执行一些任务。什么任务?

见,只要您使用的对象被创建的new运营商,以及JVM不会在字符串池的样子。它只是要创建对象,但是当你使用字符串文字创建的字符串对象则JVM将执行寻找字符串池中任务

即,当你写

String s2 = "abc";

JVM将看在串池,并检查“ABC”已经存在。如果存在,那么返回引用到已经存在字符串“abc”和一个新的对象没有创建,如果不存在,那么它创建的对象。

所以你的情况(一)

String s1 = new String("abc");
  • 由于new使用对象被创建

(b)中

String s2 = "abc";
  • 使用一个字符串被创建文字对象和“ABC”是不是在串池,并因此创建对象。

(C)

String s2 = "abc";
  • 再次使用字符串文字和“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");
    }
}

我希望这有助于...注意==用于查看如果对象是平等和equals(Object)方法来看看内容是相等的。


2
投票
  1. 字符串s =新字符串( “XYZ”);

上述线将创建两个对象的一个​​是在堆和另一个是字符串常量池。

现在,如果我们做到这一点

  1. String s = new String("xyz");
  2. String s1 ="xyz";

上述两个语句将创建两个对象。第一行String s = new String("xyz");will创建两个对象在第一个行中提到,当String s = "xyz";executes它会检查字符串常量池中是否有相同的内容对象是有还是没有,因为第一线做出字符串常量池“XYZ”,它返回一个条目同样参考,并不创建其他对象。

如果我们有这四线一起如下所述。

  1. String s2 = new String("xyz");
  2. String s3 ="xyz";
  3. String s4 = new String("xyz");
  4. String s5 ="xyz";

如果我们执行上面的线,我们将有三个对象。

  • 第一和如所提到的将创建两个对象在一个堆,另一个在字符串常量轮询。
  • 当第二线执行它检查在字符串常量轮询 并以“XYZ”中找到,因此返回相同的对象,所以直到第二行,我们有两个对象。
  • 当第三行执行它会在堆中创建一个新的对象,因为新的运营商在堆中创建对象,因此直到第三条线将有3个对象。
  • 当第四行执行它会检查字符串常量调查 并以“XYZ”中找到,因此返回相同的对象,所以第四行,我们有三个对象。

奖金有关intern()方法

当实习生()方法是一个String对象上调用它看起来在泳池此String对象中包含的字符串,如果字符串被发现存在则返回从池中的字符串。否则,这个String对象添加到池中,并返回此String对象的引用。

public class TestString {

    public static void main(String[] args) {
        String s1 = "Test";
        String s2 = "Test";
        String s3 = new String("Test");
        final String s4 = s3.intern();
        System.out.println(s1 == s2);
        System.out.println(s2 == s3);
        System.out.println(s3 == s4);
        System.out.println(s1 == s3);
        System.out.println(s1 == s4);
        System.out.println(s1.equals(s2));
        System.out.println(s2.equals(s3));
        System.out.println(s3.equals(s4));
        System.out.println(s1.equals(s4));
        System.out.println(s1.equals(s3));
    }

}

//Output
true
false
false
false
true
true
true
true
true
true

通过对新的字符串对象将实习生方法见实习生的魔力。在字符串常量池的实习生是用在这里,因此会检查是否“测试”,请在字符串常量池中与否,因为“测试”可用,它会返回相同的对象,以便s3具有同一基准s1s2,将得到所有的结果为真

public class TestString {

    public static void main(String[] args) {
          String s1 = "Test";
	        String s2 = "Test";
	        String s3 = new String("Test").intern(); 
	        final String s4 = s3.intern();
	        System.out.println(s1 == s2);
	        System.out.println(s2 == s3);
	        System.out.println(s3 == s4);
	       System.out.println(s1 == s3);
	        System.out.println(s1 == s4);
	        System.out.println(s1.equals(s2));
	        System.out.println(s2.equals(s3));
	        System.out.println(s3.equals(s4));
	        System.out.println(s1.equals(s4));
	        System.out.println(s1.equals(s3));
    }

}

true
true
true
true
true
true
true
true
true
true

2
投票

如果我们执行String s = new String("Brajesh");,应创建了两个对象。一个对象会在字符串常量池中,另一个在堆区中创建。但是,如果我们已经有相同的字符串文本对象,然后只创建一个对象。喜欢

String s1  ="Brajesh"; 
String s = new String("Brajesh");//it will create only one object in heap area

除了这一个附加的目的还在于为char的[]对象堆区中创建。我在这里附加堆内存的快照。 enter image description here


1
投票

2个或3个对象被创建,这取决于编译器如何聪明是。

然而,你的测试是垃圾,因为hashCodes的String是基于String的内容,而不是他们的身份。如果您要检查身份,你应该使用System.identityHashCode或只是==比较。

编译器和运行时允许(不强制)尽可能优化字符串创建。因此,他们优化文本字符串,通过使用单一的文字对你有三根弦。无论如何,new经营者必须返回一个新的对象(即一个新分配的一个)。如果静态方法String.valueOf来代替在运行时字符串优化是可能的。但我不知道是否有缓存实际上是由当前的JRE(也许是更昂贵的检查哈希表,而不是只分配一个新的String)应用


1
投票
        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

正如我们在上面的程序看,我们已经看到了类似的哈希码S2和S4分别尽管我们使用==操作符变得虚假。 ==运算符用于基准比较。

两个物体已经在“字符串S4 =新字符串(”孟买“)”,一个在堆存储器和一个在栈存储器被创建。因此S2比较与在堆内存中创建的,不与栈存储器S4。


1
投票
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;
}

如果我们看到的代码,我们可以看到它只是创造一个char [],它将会被复制内容相同,每次实例化,并肯定将数据存储在字符串常量池的。 1)会从SCP字符串S1 = “一个” 字符串S2 = “一”; 2)创建新的对象的字符串S3 =新字符串( “A”);好奇心,新对象字符串s2 =新字符串( “A”);在所有上面的代码相同的char []将得到copied.i:电子的char []值You can check here


1
投票

如果新的String()创建2个对象(一个堆,一个在字符串池),那么有什么用.intern方法吗?

引用一个String对象的实习生()方法查找由池中此String对象中包含的字符串,如果字符串被发现存在则返回从池中的字符串。否则,这个String对象添加到池中,并返回此String对象的引用。

© www.soinside.com 2019 - 2024. All rights reserved.