OCJP考试模拟中的错误:真正创建了多少个对象?

在OCJP认证的模拟中,我发现了这个问题:

1. StringBuffer s1 = new StringBuffer("abc"); 2. StringBuffer s2 = s1; 3. StringBuffer s3 = new StringBuffer("abc"); How many objects are created ? 

他们说正确的答案是4,因为他们声明:

 s1 is one object, s2 is another object, s3 is another object and "abc" is another String Object . 

但对我来说这是错误的,应该是3,因为s1s2是同一个对象。 你怎么看?

你是对的,答案不是4个对象。

但是,“创建了多少个对象”的问题是模棱两可的。 问题是执行代码时不会创建三个对象之一。 具体来说, 实际上在加载代码时创建与"abc"文字对应的String对象。 执行该代码时,将创建两个StringBuffer对象,并使用预先存在的String对象。

实际上它比这更复杂,因为在类加载时,可能会创建另一个临时String对象,然后在它被实现后丢弃;

  • 如果已经在另一个类中加载了"abc"文字,那么将使用该文字。

  • 如果字符串池实现需要将其放入池中,则不会指定它是否为String的新副本。

除非更准确地说明问题,否则没有一个正确的答案。 你能说的最好的是:

  • 运行代码时会创建两个StringBuffer对象。
  • 加载代码时会创建一个或两个String对象。

然后是你是否应该计算构成StringBufferString对象一部分的私有char[]对象的问题。 这可能会将对象数量增加到8。

肯定是3 Object.both s1和s2引用相同的位置。 所以s1,s2和“abc”就是这里的对象。 可能最好不要遵循该参考。

更正

应该有3个对象:

 1. StringBuffer s1 = new StringBuffer("abc"); 

将在内存s1和“abc”中创建两个对象。 这是因为,字符串被中断并且文字被添加到内存池中。

 2. StringBuffer s2 = s1; 

此处不会创建任何对象,因为s2将指向作为s1的一部分创建的“abc”

 3. StringBuffer s3 = new StringBuffer("abc"); 

只为s3创建一个对象。

怎么样:

 1. StringBuffer s1 = new StringBuffer("abc"); 

1个builder对象+ 1个char[]对象+(1个字符串文字,如果已创建)

 2. StringBuffer s2 = s1; 

没有新对象。

 3. StringBuffer s3 = new StringBuffer("abc"); 

1个builder对象+ 1个char[]对象

StringBuilder 封装了内部的后台char [],它一个对象。

正如@StephenC所说,这个问题含糊不清。

3或4,取决于实施。 有些编译器只会为常量“abc”创建一个String对象,并根据需要多次引用它,而其他编译器会为每个常量创建一个对象。 AFAIK,所有语言规范版本都没有强制要求,并且将来可能会再次发生变化。

或者更多,取决于StringBuffer的实现(它可以主动创建一个char []并复制初始化String,而不是延迟实现,直到StringBuffer的内容真正被更改)。 同样,这不应该由语言强制执行。 而且,BTW,为了问题的目的,数组是否算作Object ? 如果StringBuffer实现在JNI结构中存储信息怎么办? 什么算作对象? 我只是想重新强调我对非语言规定的实现细节的观点。

测试不应该问这类问题,除非是关于特定实现和/或JLS版本。

绝对清楚的是,他们给出答案4的原因是完全错误的。 对s2的赋值不会导致创建任何新对象。