4

String[]所以我只是尝试从main方法中排除args

它编译好了!

但是 JVM 显示异常

为什么String[]每次都必须包含 args 时它会编译?

这里发生了什么 ?为什么它不会显示编译错误?

输入这个让我觉得可能是编译器没有把它看作是main方法..是这样吗?

如果是这样的话..为什么不呢?我的意思是不应该只有一种主要方法必须以String[]args 作为参数吗?

4

13 回答 13

6

JVM 正在寻找一种非常特殊的 main 方法来运行。只有签名

public static void main( String[] args )

被发现。所有其他带有名称的方法main都只是“普通”方法。

于 2010-05-21T19:58:46.787 回答
6

输入这个让我觉得可能是编译器没有将它视为主要方法..是这样吗?

正确的。没有编译错误,因为您可以完全自由地使用各种名为main. 但是当你启动 JVM 并给它一个“主类”时,它会static public void main(String[])在那个类中寻找一个方法,如果它没有找到这样的方法,它就会异常中止。

这使您可以在程序中拥有多个主要方法,如果您仔细想想,这确实是唯一有意义的事情:应用程序可以由来自许多不同来源的类和 JAR 文件组成,由不同的人在不同的时间编写,所以在许多情况下,您不能从一开始就真正拥有一个指定的“主类”。

于 2010-05-21T20:04:48.447 回答
4

不是每个类都必须有一个public static void main(String[] args)方法,只有你想从 JVM 运行的那个。结果是,如果你的类找到了,它将编译而没有错误,public static void main()但如果你尝试使用 JVM 运行它,则会抛出异常,因为它找不到程序的入口点。

最重要的是,程序的入口点public static void main(String[] args)必须位于至少一个 .java 文件中。

请注意,您的代码中可以有多个public static void main(String[] args)方法(每个类一个),优点是您可以使用这些方法单独测试和调试您的类。

于 2010-05-21T20:08:12.523 回答
4

要尝试回答“为什么在没有适当的 main 方法的情况下编译是合法的”,这是因为并非每个 java 项目都是可以运行的独立应用程序。有些只是库,其他程序会将它们作为 jar 文件包含并使用它们的代码,但它们不会“运行”自己。其他的可能是 web 应用程序,它们被部署到已经启动的 web 服务器上,只有服务器本身实际上有一个适当的“main”方法。Web 应用程序项目由它打开并执行。

编译器在编译时并不真正知道您打算尝试将代码作为独立应用程序运行。

于 2010-05-21T20:09:13.207 回答
3

Java 支持方法重载。这意味着您可以拥有多个名称相同但参数不同的方法。

话虽如此,当您运行时java ClassName,Java 会查找ClassName.class带有签名的方法public static void main (String[])(它不关心String[]变量的名称)并运行它。如果它没有找到,Java 将出现以下异常:

线程“main”中的异常 java.lang.NoSuchMethodError: main

于 2010-05-21T20:01:47.623 回答
2

你是对的。运行时正在寻找一个将字符串数组作为参数的 main 方法,但没有找到它。

您有一个不采用字符串数组的 main 方法这一事实无关紧要。就像任何其他方法一样,您可以创建main()采用不同参数的多个版本 - 运行时将忽略它们。

于 2010-05-21T20:00:29.267 回答
1

不是超载吗?定义一个方法是完全合法的

static void main() {
}

这不是 JVM 将要寻找的入口点。

重载是拥有多个同名参数不同方法的能力。编译器实际上根据方法名称和参数创建了一个名称。

因此,编译器会调用 main(String[]),类似于 main_String_arr,而 main() 将被称为 main。

于 2010-05-21T19:59:45.307 回答
1

是的..

Java 编译器将寻找相同的方法签名以将其视为main

编写任何具有相同名称但另一个参数的函数将导致重载函数..
重载的函数不一样..!!

C# 中的情况有些不同..

最后,你必须确保你的 main 是这样的:

 public static void main(String[] args) 
于 2010-05-21T19:59:46.257 回答
1

您可以有许多名为 main 的方法,但只有一个可以是主方法 - 程序的入口点。它是带有 String[] 参数的那个。

于 2010-05-21T20:00:02.810 回答
1

这仍然是一个有效的方法。例如,如果需要,可以有一个名为“main”的静态方法,带有一个 int 参数:

public static void main(int foo){}

编译器不会抱怨,因为它是一个有效的方法!只是,为了运行 Java 程序,Java 使用单个字符串数组参数查找名为“main”的静态方法。

于 2010-05-21T20:00:46.583 回答
1

您可以使用编译器来编译应用程序的一部分:例如,制作一个 jar 文件,您将从应用程序的另一部分调用该文件;或以不同方式启动的小程序。因此编译器不能抱怨缺少 main(String[]) 方法。但是试图运行这样一个编译的结果。

当你尝试运行这样的编译结果时,java 总是在寻找特定的 main(String[]); 如果找不到它,它将引发运行时异常。用于启动应用程序的 main 必须具有签名。

于 2010-05-21T20:07:48.750 回答
1

这是来自Java 教程/入门的引用:

在 Java 编程语言中,每个应用程序都必须包含一个 main 方法,其签名是:

public static void main(String[] args)

修饰符publicandstatic可以按任意顺序(public staticstatic public)编写,但约定public static如上所示使用。您可以为参数命名任何您想要的名称,但大多数程序员选择“ args”或“ argv”。

main方法类似于C和C++中的main函数;它是您的应用程序的入口点,随后将调用您的程序所需的所有其他方法。

所以准确地说, main方法是由Java定义为应用程序入口点的。并非所有东西都是应用程序,也不是每个main方法都是应用程序入口点。例如,小程序不需要main,因为它以不同的机制开始。

另请注意,由于引入了可变参数,您实际上可以如下声明您的应用程序入口点:

 public static void main(String... args)

这是因为在语法糖之下,Java 中的可变参数是作为数组实现的。

也可以看看

相关问题

于 2010-05-22T06:08:08.383 回答
0

要点:

  1. 以下是 main 方法的签名:

    public static void main(String[] args)
    
  2. main 方法可以重载。

  3. 多个类可以在一个编译单元中包含 main 方法(因此它们都将被称为可执行类)

  4. 包含 main 方法的类可能是公共的,也可能不是公共的。

  5. 错误地,如果您省略了 static 关键字(或签名以任何方式不同),编译将完成,但会发生运行时错误。

从我的博客:

Java:关于 main 方法的要点

于 2014-10-20T17:26:55.560 回答