方法深度解析:继承常见问题

在 Java 编程的世界里,main 方法是每个 Java 程序员的起点每一个 Java 学习者都是从编写一个包含 public static void main(这个看似简单的方法背后,其实隐藏着不少有趣且实用的知识点。今天,我们就来深入探讨一下main` 方法的几个常见问题,尤其是关于它能否被继承的疑问。

main 方法的基本构成

首先,让我们回顾一下 main 方法的基本构成:

  • public:因为 JVM(Java 虚拟机)需要调用它来启动程序,所以它的访问权限必须是最大的。
  • static:调用 main 方法时,不是通过创建对象来调用的,而是直接通过类名来调用,因此它` 的。
  • void:启动程序不需要 main 方法返回任何结果,因此返回类型为 void
  • main:这是一个约定俗成的名字,JVM 只认这个名字作为程序的入口。
  • String[] args:这是传递给程序的参数。,当你在命令行传递一些参数时,JVM 会通过这接收它们。

另外,自 JDK 1.5 之后,String[] args 写成String... args`,这实际上是一种语法糖,与数组没有本质区别,只是看起来更简洁一些。

public static void main(String... args) {
    System..println("用可变参数写 main 方法");
}

main 方法能否重载?

提到重载可能会立即认为 main 方法不能重载,因为 JVM 只认标准写法作为程序入口。然而,事实并非如此。虽然 JVM 只认 public static void main(String[] args) 作为程序入口,但这并不妨碍你在类中重载 main 方法,只要参数列表不同即可。

public class Demo {
    public static void main(String[] args) {
        System.out.println("标准 main 方法");
        main("重载的 main 方法");
    }

     void main(String arg) {
        System.out.println(arg);
    }
}

运行上述代码,控制台会打印:

标准 main 方法
重载的 main 方法

这说明你可以重载 main 方法,但 JVM 只会将签名为 public static(String[] args) 的方法作为程序入口。其他重载的 main 方法与普通 static 方法无异。

main 方法能否被其他方法调用?

关于 main 方法能否被其他方法调用的问题,答案是肯定的。main 方法本质上就是一个 static 方法,只不过 JVM 拿它作为程序入口而已。因此,只要方法签名匹配,它就可以像其他 static 方法一样调用

public class Demo {
    private static int count = 3;

    public static void main(String[] args) {
        System.out.println("main 被执行:" + count);
        if (--count > 0) {
            main(args); // 自己调自己
        }
    }}

运行上述代码,会打印三次 "main 被执行:",后跟递减的计数。这说明 main 方法与其他 static 方法一样,可以被其他方法调用。

main 方法能否继承?

这是本文的核心问题。要解答这个问题,首先需要一点main 方法是 static 的,而 static 方法在 Java 中是不能被真正“重写”的,但可以被“隐藏”。也就是说,子类可以写一个与父类同名的 static 方法,这个方法会屏蔽掉父类的同名 static 方法。

public class Parent {
    public static void main(String[] args) {
        System.out.println("我是父类的 main");
    }
}

public class Child extends Parent {
    // 这里没有写 main 方法
}
运行 `Child` 类,打印 "我是 main"。这说明子类虽然没有写 `main` 方法仍然可以使用父类的 `main` 方法。换句话说,`main` 方法在类层面上是可以“继承”的。

然而,如果子类自己也写了一个 `main` 方法:

```java
public class Child {
    public static void main(String[] args) {
Systemprintln("我是子类的 main");
    }
}

运行 类,会打印 "我是子类的 main"。这说明类的 main 方法被子类的 main 方法“隐藏”掉了。

需要注意的是,Java 的入口不是你main方法 JVM 就会去执行。而是你运行哪个类,JVM 就会去找那个类的main(String[] args)方法。如果你运行的是子类,JVM 就会在子类里找main方法;如果没有找到,就会去父类里找父类也没有 就会,说找不到主类的main` 方法。

总结

经过上述分析,得出以下结论:

  • main 方法并没有多特殊。它之所以显得“特殊只是因为 JVM 把它当作程序入口。
  • main 方法可以重载,但 JVM 只会将签名为public static void main(String[] args)` 的方法作为程序入口。
  • main 方法可以被其他方法调用,因为它本质上就是一个 static 方法。
  • main 方法在类层面上是可以“继承”的,但这种“继承”实际上是 static 方法的隐藏机制。子类可以写一个与父类同名的 static 方法来隐藏父类的方法。

因此,下次再有人问你“main 方法能不能继承”,你可以淡定地告诉他:“能,但这只是类层级上的可见性,是 static 方法的隐藏机制。”