Java编译器在通过名称

时间:2018-11-27 20:21:32

标签: java eclipse compiler-errors compilation javac

我有一个内部类(例如Parent)(例如InnerClass)。 InnerClassParent的后代。这两个类都具有名称相同的private方法(例如methodA),但方法签名不同。

InnerClass中,我有调用methodA并带有签名的代码,该签名仅使类Parent中的适用方法生效。我在使用 javac 编译此类代码时遇到问题-似乎无法通过继承看到父方法,即使该方法在此范围内也可以访问。 由于有thisthis 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)?

如果祖先的私有方法可以通过定义范围访问,那么不应继承祖先的私有方法吗?

0 个答案:

没有答案