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

Posted

技术标签:

【中文标题】为啥包含 main 方法的类在 Java 中不需要是公共的? [复制]【英文标题】:Why a class containg a main method doesn't need to be public in Java? [duplicate]为什么包含 main 方法的类在 Java 中不需要是公共的? [复制] 【发布时间】:2013-09-08 04:52:43 【问题描述】:

我写了以下代码

 
  class Hello //Note the class is not public
  
        public static void main(String args[]) System.out.println("Hello");
        
   

所以,当我运行它时,它运行良好并打印输出“Hello”。

但是,如果 JVM 规范要求 main 方法应该是公共的,因为“否则它看不到 main”,它不应该也适用于类吗?如果 JVM 在未声明为 public 时“看不到” Hello.main(),它如何能够看到 A 类本身。

除了“因为规范是这么说的”之外,还有什么解释吗?

如果 JVM 能够看到所有类和方法,因为它本身就是“安全/可见性实施者”,那么为什么需要将 main 方法声明为 public。

【问题讨论】:

也可以在非默认包中运行! 好吧,忘了我当时说的话,我完全错了。 您在规范中的什么地方找到了“否则它看不到 main”的引用? 很多答案。请参阅我之前发布的类似讨论的链接,其中表明该类not 必须是Public。规范没有这样说。 【参考方案1】:

我不认为规范说该类必须是公共的。 参考官方java tutorial上的例子。示例中没有 main 方法的类被声明为 Public。

这已在 *** 上讨论过。参考:Package-private class within a .java file - why is it accessible? 解释得很好。

【讨论】:

感谢您的回复。我的问题是 JVM 需要将 main() 公开才能从任何地方访问它。但是如果包含 main() 的类不是公开的,那么 main() 公开的目的是什么(即它的可见性受到该类的限制)【参考方案2】:

请注意main 是早期语言功能。我的猜测是,有人认为私有方法可能会在 .class 文件中消失,可能是内联的,可能是更短的名称。所以这是一个简单的过度限制 (?) 约定,用于检索正确的方法:

static void main(String[])

【讨论】:

【参考方案3】:

默认访问说明符是包。类可以访问同一包中其他类的成员。但是在包之外它显示为私有但 JVM 可以访问所有类,因此 JVM 可以更改可见性只是为了找到开始的程序,因此它默认设置为默认值

【讨论】:

【参考方案4】:

首先让我们考虑一下 1. 由于main方法是静态Java虚拟机可以调用它,而无需创建任何包含main方法的类的实例。

这个: 2.Java中类中声明的任何东西都属于引用类型,并且需要在使用它们之前创建对象,但是静态方法和静态数据被加载到JVM内部称为上下文的单独内存中,该内存是在加载类时创建的。如果 main 方法是静态的,那么它将在 JVM 上下文中加载并可供执行。

最后是这个: 3. Main 方法是任何Core Java 程序的入口点。从 main 方法开始执行。

总之:Java 首先为您的 Main 方法充电,public 使 JVM 可以从任何地方访问此方法,static 在 JVM 上下文中设置该方法,因此 JVM 加载的第一件事就是您的 main方法!

Class Hello

只需让同一个包中的所有类都可以访问您的类。

【讨论】:

【参考方案5】:

如果 JVM 规范要求 main 方法应该是公开的,因为“它不能 否则请参阅主要内容”

它可以看到,但它不将其视为入口点,这就是为什么如果您尝试执行没有此类方法的类,它会给出 NoSuchMethodError: main

通过经典设计,主要入口点-

    必须命名为 ma​​in 必须公开 必须是静态的 必须无效 必须有一个参数,即字符串数组

因此,

public static void main(String args[])

由于是静态的,JVM 可以在不创建任何包含 main 方法的类实例的情况下调用它。不确定这是否是 main 被设计为 static 的主要原因。

在您的示例中像 Hello 这样具有默认访问权限的类仅对同一包中的其他类可见。

【讨论】:

您应该添加第 5 点:“必须命名为 main”。 @TedHopp 不知道我怎么没有说出来。谢谢。 @SajalDutta 谢谢伙计。您的解释准确而令人满意! @KhanZaid 欢迎你.. @SajalDutta 这也是不能将类声明为私有、受保护的原因之一吗?【参考方案6】:

Here's 一个类似的问题,答案非常简单。

基本上,JVM 可以访问任何具有default 访问权限或public 访问权限的类中的main,因为它是入口点。如果类是privateprotected,你会得到一个编译错误。

【讨论】:

是什么让你认为你会得到一个编译错误? 因为我试过了;-) 外部类只能有一个public 访问修饰符。但是内部类当然可以是privateprotected 根据我的研究,一个类只能有 2 个访问修饰符。公开或默认。【参考方案7】:

JVM 启动时,它会加载命令行中指定的类(请参阅jls java virtual machine start up),并且您不能在类中使用protectedprivate 说明符,因此您唯一的选择是拥有public 或只是空白 default 并且这两个访问说明符都允许在同一个包中访问该类。所以加载类不需要指定public关键字。

希望它清楚。

【讨论】:

您是否认为必须将 main 声明为 public 的原因是它可以被 JVM 访问,或者它只是语法的一部分,就像 Java 开发人员希望我们遵循他们的语法一样!【参考方案8】:

随便玩,私教也能开的demomain

class Outer 
    private static class Inner 
        public static void main(String[] args) 
            System.out.println("Hello from Inner!");
        
    

从命令行编译并运行良好:

C:\junk>javac Outer.java C:\junk>java Outer$Inner 来自内心的你好!

C:\垃圾>

【讨论】:

很好,从来不知道这是可能的。 请注意,在linux bash中,您需要对其进行转义,即java Outer\$Inner才能运行。

以上是关于为啥包含 main 方法的类在 Java 中不需要是公共的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

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

为啥某些 Tailwind 类在 JetStream 中不起作用?

父组件的类在子组件中不起作用

java基础(初始化和清理)

java 里为啥有些类在生成对象的时候需要复写一些方法呢?这是怎么回事?

为啥在 C++ 中的类中不需要“&”引用?