覆盖 - 将方法的可见性降低为私有,eclipse 错误
Overriding - reducing visibility of a method as private, eclipse error
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();
}
}
在第二个class中,我们有一个私有方法"methodOne"。这在 eclipse 中显示错误 "Cannot reduce the visibility of the inherited method from First"。
我知道这个错误是因为 覆盖方法不应该降低可见性
即使它显示编译错误,它也能正常执行并给出输出 in Parent methodOne
。如果是编译错误,为什么会产生输出?
当我将访问说明符更改为受保护时,它在控制台中给出了预期的编译错误!
如果您想覆盖子 class 中的方法,子 class 中指定方法修饰符的范围必须大于基 class。
就像你的程序一样,class 中的方法 methodOne 的修饰符必须是 public.
是的,我可以在 Spring 工具套件版本:3.7.0.RELEASE 中重现该问题。
虽然有待处理的错误,当强制为 运行 虽然有错误时,会出现 in Parent methodOne 输出。 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();
由于classSecond
没有methodOne
的方法,First
class中的methodOne
方法是打电话。
假设您在第二个中将 methodOne
声明为 Public
。
然后你会得到 methodOne 作为输出。
覆盖时,
- 访问静态字段、实例字段和静态方法依赖于引用变量class和不是实际对象 变量指向的。
- 这与实例方法的情况相反。
在实例方法的情况下,调用对象的实际class中的方法。
考虑以下示例。
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
}
希望这对您有所帮助。
我认为那是 Eclipse 编译器的 "magic",无论如何它都会尝试编译它。
此示例运行良好,因为在运行时,错误的方法 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
-Object-Reference 无法访问),所以 First.methodOne
被调用.当它的 protected
实际上是 "reachable" 代码时,因此抛出异常。
- Eclipse 已按照 Java 语言规范(JLS ).
- 即使存在编译错误,此编译器也可以创建 CLASS 个文件。但是,如果出现严重错误(例如,引用不一致的二进制文件,很可能与无效的构建路径有关),Java 构建器不会生成任何 CLASS 文件。
如果勾选 Class Second
使用 decompiler
,methodOne
将如下所示
private void methodOne()
{
throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
}
由于引用是父类 class 并且方法可见,因此调用父类方法。
Eclipse 编译器识别 methodOne
是父类的重写方法,应遵循重写方法规则。
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();
}
}
在第二个class中,我们有一个私有方法"methodOne"。这在 eclipse 中显示错误 "Cannot reduce the visibility of the inherited method from First"。
我知道这个错误是因为 覆盖方法不应该降低可见性
即使它显示编译错误,它也能正常执行并给出输出 in Parent methodOne
。如果是编译错误,为什么会产生输出?
当我将访问说明符更改为受保护时,它在控制台中给出了预期的编译错误!
如果您想覆盖子 class 中的方法,子 class 中指定方法修饰符的范围必须大于基 class。 就像你的程序一样,class 中的方法 methodOne 的修饰符必须是 public.
是的,我可以在 Spring 工具套件版本:3.7.0.RELEASE 中重现该问题。 虽然有待处理的错误,当强制为 运行 虽然有错误时,会出现 in Parent methodOne 输出。 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();
由于classSecond
没有methodOne
的方法,First
class中的methodOne
方法是打电话。
假设您在第二个中将 methodOne
声明为 Public
。
然后你会得到 methodOne 作为输出。
覆盖时,
- 访问静态字段、实例字段和静态方法依赖于引用变量class和不是实际对象 变量指向的。
- 这与实例方法的情况相反。
在实例方法的情况下,调用对象的实际class中的方法。
考虑以下示例。
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
}
希望这对您有所帮助。
我认为那是 Eclipse 编译器的 "magic",无论如何它都会尝试编译它。
此示例运行良好,因为在运行时,错误的方法 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
-Object-Reference 无法访问),所以 First.methodOne
被调用.当它的 protected
实际上是 "reachable" 代码时,因此抛出异常。
- Eclipse 已按照 Java 语言规范(JLS ).
- 即使存在编译错误,此编译器也可以创建 CLASS 个文件。但是,如果出现严重错误(例如,引用不一致的二进制文件,很可能与无效的构建路径有关),Java 构建器不会生成任何 CLASS 文件。
如果勾选 Class Second
使用 decompiler
,methodOne
将如下所示
private void methodOne()
{
throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
}
由于引用是父类 class 并且方法可见,因此调用父类方法。
Eclipse 编译器识别 methodOne
是父类的重写方法,应遵循重写方法规则。