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,因为s1
和s2
是同一个对象。 你怎么看?
你是对的,答案不是4个对象。
但是,“创建了多少个对象”的问题是模棱两可的。 问题是执行代码时不会创建三个对象之一。 具体来说, 实际上在加载代码时会创建与"abc"
文字对应的String
对象。 执行该代码时,将创建两个StringBuffer
对象,并使用预先存在的String
对象。
实际上它比这更复杂,因为在类加载时,可能会创建另一个临时String
对象,然后在它被实现后丢弃;
-
如果已经在另一个类中加载了
"abc"
文字,那么将使用该文字。 -
如果字符串池实现需要将其放入池中,则不会指定它是否为
String
的新副本。
除非更准确地说明问题,否则没有一个正确的答案。 你能说的最好的是:
- 运行代码时会创建两个
StringBuffer
对象。 - 加载代码时会创建一个或两个
String
对象。
然后是你是否应该计算构成StringBuffer
和String
对象一部分的私有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
的赋值不会导致创建任何新对象。