本文介绍了如果在构造函数中使用super调用重写的方法会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 有两个类 Super1 和 Sub1There is two classes Super1 and Sub1 Super1.classSuper1.classpublic class Super1 { Super1 (){ this.printThree(); } public void printThree(){ System.out.println("Print Three"); }} Sub1.classSub1.classpublic class Sub1 extends Super1 { Sub1 (){ super.printThree(); } int three=(int) Math.PI; public void printThree(){ System.out.println(three); } public static void main(String ...a){ new Sub1().printThree(); }}当我调用方法我希望输出为类 Sub1 的printThree :When I invoke the method printThree of class Sub1 I expected the output to be:因为 Sub1 构造函数,调用 super.printThree(); 。 但我实际上得到了我知道0是 int 的默认值,但是它是如何发生的?I know 0 is default value of int but how it is happening ?推荐答案您正在看到三件事的影响:You're seeing the effects of three things: 默认的超级构造函数调用,以及Default super-constructor calls, and实例初始化程序(相对于超级调用),以及Instance initializers relative to super calls, and重写的方法如何工作您的 Sub1 构造函数是真的:Sub1(){ super(); // <== Default super() call, inserted by the compiler three=(int) Math.PI; // <== Instance initializers are really inserted // into constructors by the compiler super.printThree();}(令人惊讶,我知道,但这是事实。请使用 javap -c YourClass 来查看。:-))(Surprising, I know, but it's true. Use javap -c YourClass to look. :-) ) 原因看起来就是在子类可以初始化对象的其部分之前,超类必须有机会初始化其对象 。这样便得到了这种交织效果。The reason it looks like that is that the superclass must have a chance to initialize its part of the object before the subclass can initialize its part of the object. So you get this kind of interwoven effect.鉴于这就是 Sub1 真正的And given that that's what Sub1 really looks like, let's walk through it: JVM会创建实例并将所有实例字段设置为默认值(所有位)关闭)。因此,此时,三个字段存在,并且值 0 。 JVM调用 Sub1 。 Sub1 立即调用 super()( Super1 ),这会... / p>Sub1 immediately calls super() (Super1), which... ...调用 printThree 。由于 printThree 被覆盖,即使对它的调用在 Super1 的代码中,也被覆盖方法( Sub1 中的一个)被调用。这是Java实现多态的一部分。由于三个的实例初始化器尚未运行,因此三个包含 0 ,这就是输出。...calls printThree. Since printThree is overridden, even though the call to it is in the code for Super1, it's the overridden method (the one in Sub1) that gets called. This is part of how Java implements polymorphism. Since three's instance initializer hasn't been run yet, three contains 0, and that's what gets output. Super1 返回。 返回 Sub1 ,它是三个,编译器插入(确实已重定位)运行,并为三个提供一个新值。Back in Sub1, the instance initializer code for three that the compiler inserted (relocated, really) runs and gives three a new value. Sub1 调用 printThree 。由于三个的实例初始化程序代码现已运行,因此 printThree 打印 3 。Sub1 calls printThree. Since three's instance initializer code has now run, printThree prints 3.关于实例初始化程序代码被移入构造函数的过程中,您可能想知道:如果我有多个构造函数?代码移至哪一个?答案是,编译器将代码复制到每个构造函数中。 (您也可以在 javap -c 中看到它。)(如果您有一个非常复杂的实例初始化程序,那么如果编译器有效地将其转换为一个实例初始化程序,我不会感到惊讶。方法,但我没有看过。)With regard to this instance initializer code getting moved into the constructor, you might be wondering: What if I have more than one constructor? Which one does the code get moved into? The answer is that the compiler duplicates the code into each constructor. (You can see that in javap -c, too.) (If you have a really complicated instance initializer, I wouldn't be surprised if the compiler effectively turned it into a method, but I haven't looked.)如果您确实调皮了一些,并在实例init期间调用了一个方法,这会更清楚一点:(实时复制)It's a bit clearer if you do something really naughty and call a method during your instance init: (live copy)class Super{ public static void main (String[] args) { new Sub(); } Super() { System.out.println("Super constructor"); this.printThree(); } protected void printThree() { System.out.println("Super's printThree"); }}class Sub extends Super{ int three = this.initThree(); Sub() { this.printThree(); } private int initThree() { System.out.println("Sub's initThree"); return 3; } protected void printThree() { System.out.println("Sub's printThree: " + this.three); }}输出:Super constructorSub's printThree: 0Sub's initThreeSub's printThree: 3注意, Sub's initThree按顺序出现。Note where "Sub's initThree" came in that sequence. 这篇关于如果在构造函数中使用super调用重写的方法会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-01 20:28