Java 实例化

2022-01-16 00:00:00 oop jvm java
  1. 当一个对象在 Java 中被实例化时,真正进入内存的是什么?
  2. 是否包含父构造函数的副本?
  3. 为什么隐藏数据成员在强制转换时的行为与被覆盖的方法不同?

我理解通常用于让您正确使用这些东西的抽象解释,但 JVM 是如何真正做到这一点的.

I understand the abstract explanations that are typically given to get you use this stuff correctly, but how does the JVM really do it.

推荐答案

当一个对象被实例化时,实际上只有非静态数据被创建",以及对创建它的对象类型的引用.

When an object is instantiated, only the non-static data is actually "Created", along with a reference to the type of object that created it.

p>

没有任何方法被复制.

None of the methods are ever copied.

对创建它的类的引用"实际上是一个指针调度表.每个类可用的方法都有一个指针.指针始终指向方法的正确"(通常是对象树中最低/最具体的)实现.

The "Reference" to the class that created it is actually a pointer dispatch table. One pointer exists for each method that is available to the class. The pointers always point to the "correct" (usually the lowest/most specific in the object tree) implementation of the method.

这样,如果您对另一个方法进行了顶级调用,但另一个方法已被覆盖,则将调用被覆盖的方法,因为那是表中指针所指向的位置.由于这种机制,调用被覆盖的方法应该不会比顶级方法花费更多的时间.

That way if you have a top-level call to another method, but the other method has been overridden, the overridden method will be called because that's where the pointer in the table points. Because of this mechanism, it shouldn't take more time to call an overridden method than a top-level one.

指针表+成员变量是类的实例".

The pointer table + member variables are the "Instance" of a class.

变量问题与完全不同的机制名称空间"有关.变量根本不是子类"(它们不进入调度表),但公共或受保护的变量可以被局部变量隐藏.这一切都是由编译器在编译时完成的,与您的运行时对象实例无关.编译器会确定您真正想要的对象,并将对该对象的引用填充到您的代码中.

The variable issue has to do with a completely different mechanism, "Name spaces". Variables aren't "Subclassed" at all (They don't go into the dispatch table), but public or protected variables can be hidden by local variables. This is all done by the compiler at compile time and has nothing to do with your runtime object instances. The compiler determines which object you really want and stuffs a reference to that into your code.

范围规则通常倾向于最近"变量.任何更远的具有相同名称的内容都将被忽略(阴影),以支持更近的定义.

The scoping rules are generally to favor the "Nearest" variable. Anything further away with the same name will just be ignored (shadowed) in favor of the nearer definition.

如果您有兴趣,可以更具体地了解内存分配:所有对象"都分配在堆"上(实际上比真正的堆更高效、更美观,但概念相同.)变量总是指针--Java 永远不会复制对象,您总是复制指向该对象的指针.方法参数和局部变量的变量指针分配是在栈上完成的,但是即使变量(指针)是在栈上创建的,它们所指向的对象仍然永远不会在栈上分配.

To get a little more specific about memory allocation if you are interested: all "OBJECTS" are allocated on the "Heap" (Actually something amazingly more efficient and beautiful than a true heap, but same concept.) Variables are always pointers--Java will never copy an object, you always copy a pointer to that object. Variable pointer allocations for method parameters and local variables are done on the stack, but even though the variable (pointer) is created on the stack, the objects they point to are still never allocated on the stack.

我很想写一个例子,但这已经太长了.如果您希望我输入几个具有扩展关系的类以及它们的方法和数据如何影响生成的代码,我可以...问一下.

I'm tempted to write an example, but this is already too long. If you want me to type out a couple classes with an extends relationship and how their methods and data effect the code generated I can... just ask.

相关文章