我有一个内部类(例如Parent
)(例如InnerClass
)。 InnerClass
是Parent
的后代。这两个类都具有名称相同的private
方法(例如methodA
),但方法签名不同。
在InnerClass
中,我有调用methodA
并带有签名的代码,该签名仅使类Parent
中的适用方法生效。我在使用 javac 编译此类代码时遇到问题-似乎无法通过继承看到父方法,即使该方法在此范围内也可以访问。
由于有this和this JLS文章,这种行为看起来是合理的。但是 Eclipse Java编译器可以编译代码,并且运行良好。
Eclipse:
public class Parent {
private void methodB(){}
private void methodA(String a) {}
class InnerClass extends Parent {
private void methodA(Integer a) {}
void callPrivateSuper() {
methodB(); //Eclipse BYTECODE -> INVOKESTATIC Parent.access$0 (LParent;)V
methodA(""); //Eclipse BYTECODE -> INVOKESTATIC Parent.access$1 (LParent;Ljava/lang/String;)V
}
}
}
javac:
public class Parent {
private void methodB(){}
private void methodA(String a) {}
class InnerClass extends Parent {
private void methodA(Integer a) {}
void callPrivateSuper() {
methodB();
methodA(""); //javac -> java: incompatible types: java.lang.String cannot be converted to java.lang.Integer
}
}
}
静态方法的行为相同:
Eclipse:
public class Parent {
private static void methodB(){}
private static void methodA(String a) {}
class InnerClass extends Parent {
private void methodA(Integer a) {}
void callPrivateSuper() {
methodB(); //Eclipse BYTECODE -> INVOKESTATIC Parent.access$0 ()V
methodA(""); //Eclipse BYTECODE -> INVOKESTATIC Parent.access$1 (Ljava/lang/String;)V
}
}
}
javac:
public class Parent {
private static void methodB(){}
private static void methodA(String a) {}
class InnerClass extends Parent {
private void methodA(Integer a) {}
void callPrivateSuper() {
methodB();
methodA(""); //javac -> java: incompatible types: java.lang.String cannot be converted to java.lang.Integer
}
}
}
Eclipse字节码INVOKESTATIC
让我认为它不是通过继承而是通过定义范围(this第一部分的第二步)看到此代码-但是如果删除了类 Eclipse 会像 javac 一样引发错误。
如果将Parent.methodA
访问修饰符更改为较少限制,则编译器将像JLS规定那样通过继承进行工作。
public class Parent {
void methodA(String a) {}
class InnerClass extends Parent {
private void methodA(Integer a) {}
void callPrivateSuper() {
methodA(""); //javac BYTECODE -> INVOKEVIRTUAL Parent$InnerClass.methodA (Ljava/lang/String;)V
//Eclipse BYTECODE -> INVOKEVIRTUAL Parent$InnerClass.methodA (Ljava/lang/String;)V
}
}
}
问题:
由于某些额外的编译器优化或某些错误,Eclipse的行为有所不同吗?
在这种情况下(除了我上面提到的),JLS中是否还有其他方面的内容可以解释编译器的行为(或者可能是JVMS)?
如果祖先的私有方法可以通过定义范围访问,那么不应继承祖先的私有方法吗?