为啥包含 main 方法的类没有实例化并且在 Java 中仍然可以?

Posted

技术标签:

【中文标题】为啥包含 main 方法的类没有实例化并且在 Java 中仍然可以?【英文标题】:How come the class containing the main method is not instantiated and is still OK in Java?为什么包含 main 方法的类没有实例化并且在 Java 中仍然可以? 【发布时间】:2012-05-23 23:11:33 【问题描述】:

我开始写我的第一个Java program。

class HelloWorldApp 
    public static void main(String[] args) 
        System.out.println("Hello World!"); // Display the string.
    

只要上面的代码,程序就可以正常运行。但根据我的 OOP 知识,class 只是一个抽象概念,直到你创建了一个同类对象后才会出现。然后,通过该对象,我们调用类中的方法/函数。

但在这个特定示例中,似乎即使没有创建 class HelloWorldApp 的对象,也会调用 main 方法

对象是在其他地方创建的吗?如果是这样,那部分代码如何知道我的class 名称HelloWorldApp

【问题讨论】:

【参考方案1】:

因为是static方法,所以不需要创建实例

JVM 将加载HelloWorldApp 类并在其上调用静态方法,并且由于它是公共 JVM(外部)可以访问该方法


另见

why-is-the-java-main-method-static

【讨论】:

这是否意味着我可以在任何其他类中调用任何静态函数?是不是淡化了封装的概念? 是的,你可以,静态字段/方法与类相关联(每个类加载而不是对象),如果它们是公共的,你可以这样做 封装不是编译器强制执行的规则,而是程序员用来尝试创建更好代码的原则。语言和编译器可以帮助我们实现封装,但不会强加于我们。即使是像 Smalltalk 这样的纯面向对象语言也不会强迫您遵循封装。然而,在 Smalltalk 中,类本身就是真实的对象,因此您可以向它们发送它们响应的消息。您甚至可以在子类中继承它们并让子类调用 super。【参考方案2】:

Java 应用程序的起点(并不总是)是这个方法

public static void main(String[] args) 
        System.out.println("Hello World!"); // Display the string.
    

当您执行java className 时,它会检查该类是否具有 main 方法,因为它是静态的,因此可以在不创建实例的情况下调用它。

如果没有主方法或主方法存在但没有相同的签名,它会抛出一个RuntimeException 说明主方法未找到。

别忘了阅读A closer look at main method。

题外话:

扩展同样的想法,你不需要一个类的实例来引用它的静态方法和字段。

public class MyClass 
  public static int NUMBER = 10;

  public static void String sayHello()
    return "Hello";
  

  public void String sayBye()
    return "Bye";
  

  public static void main(String[] args)
    System.out.println(NUMBER); // No need for object 
    System.out.println(sayHello()); // No need for object 
    System.out.println(new MyClass().sayBye()); // sayBye is not accessible at class level have to have an object of MyClass to access sayBye
  

如果在其他类中调用相同的,那么它可能看起来像:

public class MyClassCaller 
   public static void main(String[] args)
    System.out.println(MyClass.NUMBER); // No need for object just refer the class
    System.out.println(MyClass.sayHello()); // No need for object just refer the class
    System.out.println(new MyClass().sayBye()); // sayBye is not accessible at class level have to have an object of MyClass to access sayBye
  

关于static methods的使用/过度使用的精彩讨论

【讨论】:

【参考方案3】:

main 方法是静态的,不需要实例

【讨论】:

以上是关于为啥包含 main 方法的类没有实例化并且在 Java 中仍然可以?的主要内容,如果未能解决你的问题,请参考以下文章

█■为啥要用实现接口的类实例化接口呢? ?

Jackson JSON 库:如何实例化包含抽象字段的类

为啥包含 main 方法的类在 Java 中不需要是公共的? [复制]

为啥main方法在java中是静态的[重复]

课程作业第二题

█■为啥要用实现接口的类实例化接口呢?