13

在模拟 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

5 回答 5

8

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

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

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

  • 如果"abc"文字已经加载到不同的类中,则将使用该文字。

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

除非问题被更准确地陈述,否则没有单一的正确答案。你能说的最好的就是:

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

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

于 2013-08-18T10:54:25.257 回答
5

是的,绝对是 3 Object.both s1 和 s2 都指的是相同的位置。所以 s1, s2 和 "abc" 是这里的对象。可能最好不要遵循该参考。

于 2013-08-18T10:03:51.293 回答
4

更正

应该有3个对象:

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

将在内存 s1 & "abc" 中创建两个对象。这是因为,字符串被保留,文字被添加到内存池中。

2. StringBuffer s2 = s1;

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

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

s3 只会创建一个对象。

于 2013-08-18T10:05:09.043 回答
2

怎么样:

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[]对象

A将支持的 char[]StringBuilder 封装在里面,它一个对象。

正如@StephenC 所说,这个问题是模棱两可的。

于 2013-08-18T10:49:45.913 回答
0

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

或者更多,取决于 StringBuffer 的实现(它可以主动创建一个 char[] 并复制初始化 String,而不是延迟实现直到 StringBuffer 的内容真正改变)。同样,这不应该由语言强制要求。而且,顺便说一句,就问题而言,数组是否算作Objects ?如果 StringBuffer 实现将信息存储在 JNI 结构中会怎样?那算什么东西?我只是想再次强调我对非语言强制实施细节的看法。

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

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

于 2013-08-18T10:48:07.807 回答