覆盖 - 将方法的可见性降低为私有,eclipse错误

时间:2015-11-27 06:19:19

标签: java eclipse override

public class First {
    public void methodOne() {
        System.out.println("in Parent methodOne");
    }

    public void methodTwo() {
        System.out.println("in Parent methodTwo");
    }
}

public class Second extends First{
    private void methodOne() {
        System.out.println("methodOne");
    }

    @Override
    public void methodTwo() {
        System.out.println("methodTwo");
    }

    public static void main(String[] args) {
        First first = new Second();
        first.methodOne();
    }
}

在第二课中,我们有一个私有方法“methodOne”。这在eclipse中显示错误为“无法降低从First继承的方法的可见性”。 我知道这个错误是因为覆盖方法不应该降低可见性

即使它显示编译错误,它也会执行正常并将输出显示为in Parent methodOne 。如果是编译错误,为什么要生成输出?

当我将访问说明符更改为protected时,它会在控制台中提供预期的编译错误!

4 个答案:

答案 0 :(得分:2)

  • Eclipse通过遵循Java语言规范( JLS )实现了自己的编译器,称为Eclipse Compiler for Java( ECJ )。
  • 即使存在编译错误,此编译器也可以创建 CLASS文件。但是,在严重错误的情况下(例如,对不一致二进制文件的引用,很可能与无效的构建路径相关),Java构建器不会生成任何CLASS文件。

如果您查看课程Second 使用decompilermethodOne将如下所示

          private void methodOne()
              {
                throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
              }

由于Reference是父类,并且方法可见,因此调用父方法。

Eclipse编译器标识methodOne是父级的重写方法,应遵循重写方法规则。

Java builder concepts -Eclipse

答案 1 :(得分:1)

是的,我可以在 Spring Tool Suite版本:3.7.0.RELEASE 中重新创建该问题。 虽然存在待处理错误,但在强制运行时虽然存在错误,但会发生父方法一输出中的。 Eclipse可能会忽略错误代码块,因为它被强制执行。

我执行了以下代码,

 class First {
    public void methodOne() {
        System.out.println("in Parent methodOne");
    }

    public void methodTwo() {
        System.out.println("in Parent methodTwo");
    }
}

 public class Second extends First{
//    private void methodOne() {
//        System.out.println("methodOne");
//    }

    @Override
    public void methodTwo() {
        System.out.println("methodTwo");
    }

    public static void main(String[] args) {
        First first = new Second();
        first.methodOne();
    }
}

我在Parent methodOne 中得到作为输出。

在代码中,您将对象分配给其父级的引用。

First first = new Second();

由于班级Second的方法不是methodOne,因此调用methodOne班级中的First方法。

假设您将第二个methodOne声明为Public

然后你会得到 methodOne 作为输出。

覆盖时,

  • 访问静态字段,实例字段和静态方法取决于变量所指向的引用变量类而不是实际对象
  • 这与实例方法的情况相反 在实例方法的情况下,调用对象的实际类中的方法。

请考虑以下示例。

    class ABCD {
        int x = 10;
        static int y = 20;

        public String getName() {
            return "ABCD";
        }
    }

    class MNOP extends ABCD {
        int x = 30;
        static int y = 40;

        public String getName() {
            return "MNOP";
        }
    }

    public static void main(String[] args) {

      System.out.println(new MNOP().x + ", " + new MNOP().y);

      ABCD a = new MNOP();
      System.out.println(a.x); // 10
      System.out.println(a.y); // 20
      System.out.println(a.getName()); // MNOP
    }

希望这有帮助。

答案 2 :(得分:1)

我认为这就是"魔术"在Eclipse编译器中,无论如何它都会尝试编译它。

此示例运行正常,因为在运行时,永远不会调用错误的方法compileError

public class EclispeCompilerErrorExample {
    public static void main(String[] args) {
        if(false) {
            compileError();
        }
        else {
            System.out.println("But run anyways");
        }
    }

    private static void compileError() {
        int i = "this wont comppile";
    }
}

private的示例有效,因为您的方法永远不会被调用(它是一个私有方法,First - 对象参考不可访问),因此调用First.methodOne。当其protected实际上是'#34;可达到'#34;代码,因此抛出异常。

答案 3 :(得分:-2)

如果你想覆盖子类中的方法,子类中指定方法修饰符的范围必须大于基类。 就像你的程序一样,方法methodOne的第二类修饰语必须是公开的。