本帖最后由 cat73 于 2016-7-31 09:25 编辑
如果你认为我说错了,请拿证据打我脸,但请不要说这是谁说过的。谢谢。
为了回答这个问题,我花了些时间去看 OpenJDK 的源代码:
http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/interpreter/bytecodeInterpreter.cpp#l2111
在上面这个地方可以看到 ldc 的实现
2134 行是 ldc String 的情况:
[C++] 纯文本查看 复制代码 case JVM_CONSTANT_String:
{
oop result = constants->resolved_references()->obj_at(index);
if (result == NULL) {
CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception);
SET_STACK_OBJECT(THREAD->vm_result(), 0);
THREAD->set_vm_result(NULL);
} else {
VERIFY_OOP(result);
SET_STACK_OBJECT(result, 0);
}
break;
}
可以看到,ldc 只是简单的从常量池里尝试获取对象,如果返回 null (没找到),则抛出异常,并不会在 ldc 这里 new String。
而 "abc" 就是通过 ldc 来获取的,也就是说,"abc" 不是 ldc 创建的,所以,这句代码执行的时候并不会创建"abc",所以,这句代码只创建了一个对象。
有兴趣的话也可以看看 ldc 的规范:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc |