简体   繁体   English

继承技术如何运作?

[英]How does inheritance technical work?

I am about to give a presentation in my company (I am a trainee) about Inheritance in Java. 我即将在我的公司(我是一名实习生)中介绍Java中的继承。 I think I figured it out and I also know how to use it. 我想我已经明白了,我也知道如何使用它。 But one thing is not so sure. 但有一点不太确定。 Where are the methodes stored in the storage. 存储在存储器中的方法在哪里。 And how does an object know where the methodes are? 对象如何知道方法的位置?

For example: 例如:

We have this class. 我们有这门课。

class Animal {
    private String desc1;
    protected String desc2;

    public void breath() {
    }

    public void eat() {
    }
}

and this class: 而这堂课:

  class Dog extends Animal() {
        public void bark() {
        }
    }

we now make an Object of the Dog class: 我们现在创建一个Dog类的对象:

Dog dog = new Dog(); 狗狗=新狗();

So now my questions: The classes are loaded in the heap. 所以现在我的问题是: 类被加载到堆中。 So Dog and Animal are in the heap. 所以狗和动物都在堆里。 (EDIT: Thats wrong, classes don't get loaded in the heap, look answers below.). (编辑:多数民众赞成错了,类没有加载到堆中,看下面的答案。)。 So, Lets say we make dog.bark() . 所以,让我们说我们做dog.bark() How does dog know where the bark method is in the Heap? 狗如何知道树皮方法在堆中的位置? Knows it where the Dog class is? 知道狗类在哪里? Next we make dog.eat(): So when dog knows where Dog is, does Dog know where Animal is or does dog know where Animal is? 接下来我们制作dog.eat():所以当狗知道Dog在哪里时,Dog会知道Animal在哪里或者狗知道Animal在哪里吗? With know I mean it has a address where it is on the heap. 知道我的意思是它有一个地址在堆上。 And how is it when I overwrite a method? 当我覆盖一个方法时怎么样? Where is that stored? 存储在哪里?

thx for helping. thx求助。

First of all, this is JVM dependent and there is no requirement in the JLS or JVM spec on how these issues should be resolved, only that they should be resolved. 首先,这是JVM依赖并且对这些问题应该如何解决在JLS或JVM规范没有要求,只是他们应该得到解决。

How does dog know where the bark method is in the Heap? 狗如何知道树皮方法在堆中的位置?

Usually you have what's called a Virtual Method Table , or v-table for short. 通常你有所谓的虚方法表 ,或简称v表。 You can think of this as a table mapping method identifiers, (such as bark ) to function pointers. 您可以将此视为表映射方法标识符(例如bark )到函数指针。 That is, if you invoke bark the VM will look into it's v-table and call the method pointed to by bark . 也就是说,如果你调用bark ,VM会查看它的v-table并调用bark指向的方法。 When you extend a class and override a method, the method pointer is simply swapped to point on the overriding function. 扩展类并重写方法时,只需交换方法指针以指向覆盖函数。

How does dog know where the bark method is in the Heap? 狗如何知道树皮方法在堆中的位置? Knows it where the Dog class is? 知道狗类在哪里?

Methods and classes are not stored on the heap in the same sense as instances are. 方法和类不以与实例相同的意义存储在堆上。 Why would they? 他们为什么?

Perhaps you have the same misconception as I had when I started with OO-programming. 也许你和我开始使用OO编程时有同样的误解。 I thought that if I instantiate 10 Dog , I get 10 bark-methods along with it. 我想如果我实例化10 Dog ,我会得到10种树皮方法。 That's not true. 这不是真的。 What you "get" when you instantiate an object, is basically it's member variables and a this reference. 实例化对象时“得到”的基本上是成员变量和this引用。 You can then see the this reference as an extra argument passed along when invoking a non-static methods. 然后,您可以this引用视为在调用非静态方法时传递的额外参数。

No, classes are not loaded into the heap (at least not what you could consider the heap in Java) but to a memory section called PermGen space. 不,类没有加载到堆中(至少不是你可以认为是Java中的堆),而是加载到一个名为PermGen space的内存部分。

I can't tell you exactly how Java stores that information, but I assume it's similar to the way that C++ does it (a vtable ), since it normally is done in JVM native code. 我无法确切地告诉你Java如何存储这些信息,但我认为它类似于C ++的方式( vtable ),因为它通常是在JVM本机代码中完成的。

First any object created in java has a class reference somewhere in the object header. 首先,在java中创建的任何对象在对象头中的某处都有一个类引用。 Linking "static" (not overriden, the JIT knows if any method is overriden but some subclass) method is easy and it can be inlined or just a call to some specific point where the code resides. 链接“静态”(不覆盖,JIT知道是否有任何方法被覆盖但是某些子类)方法很简单,它可以内联或只是调用代码所在的某个特定点。

It's way more complicated since the optimized code is called with the values held in the registers while java spec demand them on the stack. 这种方式更复杂,因为优化的代码是使用寄存器中保存的值调用的,而java规范要求它们在堆栈上。

Calling override methods is done in few ways: 调用覆盖方法以几种方式完成:

  • Dynamic check the instance and dispatch the call like in the static example, it's a single compare/branch call, much faster than 动态检查实例并像静态示例一样调度调用,这是一个比较/分支调用,比快
  • Inline caches 内联缓存
  • or already mentioned v-table calls. 或者已经提到的v-table调用。 v-tables are the slowest v表是最慢的

Understanding how the code is executed by the processor and the methods invoked/inlined, etc, is a vast topic, though. 但是,了解处理器执行代码的方式以及调用/内联的方法等是一个很大的主题。 I guess some other basic concepts are missing. 我想其他一些基本概念都缺失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM