在学习Java面向对象这一章节的时候,我们知道子类继承父类,父类中私有属性和方法不能被继承,那么子类是如何访问到父类的私有属性呢?父类的私有属性会存储在那个地方?
1、父类的成员变量(包含私有变量)和成员方法地址(包含私有成员方法)都存放在子类对象中。父类的私有变量和私有方法虽然在子类对象中,但是对于子类对象而言是不可见的,无法直接访问和调用,必须通过父类的成员方法(或者父类的构造方法)才能访问和调用,正是因为这样的特性,所以 Java 官方文档将其描述为不可以被子类继承,但是从内存数据来看,父类的私有且非静态的数据的确在子类的对象中。
2、静态变量和静态方法则不在子类对象中,存在于JVM的方法去内存中。这些资源和对象无关,都是通过类名称进行访问的。生命周期与类相同。
3、静态变量的数据存放在方法区的静态区中
4、静态变量和静态方法的声明定义的代码都在方法区中
一张图一目了然
所以,在创建子类对象时,调用父类构造方法是真的,但是根本没有创建父类对象,只不过是调用父类构造方法时,在子类对象的内存中来初始化父类的所有属性。如果说调用父类构造方法就等于创建父类对象,那就真的无稽之谈。
1、new指令开辟空间,用于存放对象的各个属性、引用等,反编译字节码你会发现只有一个new指令,所以开辟的是一块空间,一块空间就放一个对象。
2、然后,子类调用父类的属性,方法啥的,那并不是一个实例化的对象。
3、在字节码中子类会有个u2类型的父类索引,属于CONSTANT_Class_info类型,通过CONSTANT_Class_info的描述可以找到CONSTANT_Utf8_info,然后可以找到指定的父类啊啥的。
4、你的方法啊,属性名称都是在这个上面解析出来的,然后实际变量内容存储在new出来的空间那里。。。
5、super这个关键字只不过是访问了这个空间特定部分的数据(也就是专门存储父类数据的内存部分)。。。。。。
6、默认的hashcode和equals(或直接使用的==比较)都是一样的,所以,这根本就在一个空间里,也不存在单独的出来的父类对象。
7、在调用子类的方法时会先在子类中寻找那个方法,找到后调用成功,否则再去父类中找想要调用的方法。如果在子类中找到了那个方法,则子类重写了父类的方法。
8、压根不存在单独的父类对象,子类只是继承了父类的代码,整个对象实例就是子类这一个,super是为了显式调用子类对象实例中父类的这部分代码。