重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇文章为大家展示了java继承中会不会自动创建父类对象,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
成都创新互联公司长期为成百上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为兴国企业提供专业的成都网站建设、网站建设,兴国网站改版等技术服务。拥有十余年丰富建站经验和众多成功案例,为您定制开发。
1.
调用父类构造方法是真的,但是根本没有创建父类对象,只不过是调用父类构造方法来初始化属性。
如果说调用父类构造方法就等于创建父类对象,那就真的无稽之谈。
new指令开辟空间,用于存放对象的各个属/性引用等,反编译字节码你会发现只有一个new指令,所以开辟的是一块空间,一块空间就放一个对象。
然后,子类调用父类的属性,方法啥的,那并不是一个实例化的对象。
在字节码中子类会有个u2类型的父类索引,属于CONSTANT_Class_info类型,通过CONSTANT_Class_info的描述可以找到CONSTANT_Utf8_info,然后可以找到指定的父类啊啥的。
你的方法啊,属性名称都是在这个上面解析出来的,然后实际变量内容存储在new出来的空间那里。。。
super这个关键字只不过是访问了这个空间特定部分的数据(也就是专门存储父类数据的内存部分)。。。。。。
默认的hashcode和equals(直接使用的==比较)都是一样的,所以,这根本就在一个空间里,也不存在单独的出来的父类对象。
如果说子类可以强行转换成父类进行使用,那是因为java虚拟机有个静态类型(外观类型)和实际类型的概念。
如Object t=new Point(2,3);
那么Object属于静态类型(外观类型),Point属于实际类型。
静态类型和实际类型在程序中都可以发生变化,区别是静态类型的变化仅仅发生在使用时发生,而变量本身的静态类型不会改变,并且最终的静态类型是在编译期间可知的;而实际变量类型的变化结果只有在运行期间才能被确定,编译器在编译的时候并不知道变量的实际类型是什么。
2.
java对象的内存布局是由对象所属的类确定。也可以这么说,当一个类被加载到虚拟机中时,由这个类创建的对象的布局就已经确定下来的啦。
Hotspot中java对象的内存布局:
每个java对象在内存中都由对象头和对象体组成。
对象头是存放对象的元信息,包括该对象所属类对象Class的引用以及hashcode和monitor的一些信息。
对象体主要存放的是java对象自身的实例域以及从父类继承过来的实例域,并且内部布局满足由下规则:
规则1:任何对象都是8个字节为粒度进行对齐的。
规则2:实例域按照如下优先级进行排列:长整型和双精度类型;整型和浮点型;字符和短整型;字节类型和布尔类型,最后是引用类型。这些实例域都按照各自的单位对齐。
规则3:不同类继承关系中的实例域不能混合排列。首先按照规则2处理父类中的实例域,接着才是子类的实例域。
规则4:当父类中最后一个成员和子类第一个成员的间隔如果不够4个字节的话,就必须扩展到4个字节的基本单位。
规则5:如果子类第一个实例域是一个双精度或者长整型,并且父类并没有用完8个字节,JVM会破坏规则2,按照整形(int),短整型(short),字节型(byte),引用类型(reference)的顺序,向未填满的空间填充。
以上就是java对象的内存布局的规则。
接下来说一下java对象的实例化方法,也就是常见的
当我们new一个对象时,其实jvm已经把这个对象的整个空间已经分配好,并且整个对象的实例域布局已经确定下来啦。
实例化方法
还是以一个例子说明一下:
class Parent { private short six; private int age; } class Sub extend Parent{ private String name; private int age; private float price; }
上述内容就是java继承中会不会自动创建父类对象,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。