Java初学者关于main方法中的String[] args参数的问题

4

我刚尝试从 main 方法中排除 String[] args 参数

它编译得很好!

但 JVM 显示了一个异常

为什么每次都必须包含 String[] args,而它却可以编译?

这是怎么回事?为什么不会显示编译错误?

打这个让我想到,也许编译器没有把它看作是 THE main 方法..那是真的吗?

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


附注:您也可以将其声明为:public static void main(String... args) - OscarRyz
我明白了,谢谢大家。虽然我还没有读过关于重载的内容,但现在我有一个想法了。我刚刚尝试用两个main函数运行程序,它正常工作。 - Serenity
但是JVM正在显示一个异常:是什么异常? - Raedwald
13个回答

6
JVM正在寻找一个非常特殊的main方法来运行。只有特定的方法签名才能被识别并执行。
public static void main( String[] args )

找到了名为main的方法。所有其他名称为main的方法都只是“普通”方法。


1
为什么编译器无法检测到主函数缺少String[] args参数的错误? - Serenity
1
因为你不必拥有一个 main 方法。你可以自由定义一个 JVM 不应该运行程序的方法。 - tangens
因为您可以使用相同名称但具有不同参数的多个方法实例 - 这被称为“重载”。 - Aaron

6
打这个代码让我想到,也许编译器没有将其视为主方法,是这样吗?
正确。没有编译错误,因为你可以自由地拥有各种名为main的方法。但是当你启动JVM并给它一个“主类”时,它会在该类中查找一个名为static public void main(String [])的方法,如果找不到这样的方法,就会中止并报错。
这允许您在程序中拥有多个主方法,并且实际上是唯一有意义的事情,如果您考虑一下:应用程序可以由来自不同来源、不同时间撰写的类和JAR文件组成,因此在许多情况下,您不能从一开始就拥有单个指定的“主类”。

4
并非每个类都必须有一个public static void main(String[] args)方法,只有你想从JVM中运行的那个类才需要。如果找到了public static void main(),则该类将编译通过,但如果尝试使用JVM运行它,则会抛出异常,因为程序的入口点无法找到。
总之,您的程序的入口点必须是至少一个.java文件中的public static void main(String[] args)方法。
请注意,您可以在代码中拥有多个public static void main(String[] args)方法(每个类一个),这样做的好处是可以单独测试和调试每个类。

4
尝试回答“为什么可以在没有正确的主方法的情况下编译”的问题,这是因为并非每个Java项目都是可运行的独立应用程序。有些只是库,其他程序将它们作为JAR文件包含并使用它们的代码,但它们本身不会“运行”。另一些可能是Web应用程序,在这种情况下,它们被部署到已经启动的Web服务器上,只有服务器本身才有一个正确的“main”方法。Web应用程序项目由其执行。
编译器在编译时并不真正知道您打算尝试将代码作为独立应用程序运行。

正确。换句话说,在不同的环境中,Java可执行JAR文件可以有不同的“起始点”,即小程序-> void init(),而在服务器上则更复杂的约定。 - Jacek Cz

3

Java支持方法重载。这意味着你可以有几个同名但参数不同的方法。

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

Exception in thread "main" java.lang.NoSuchMethodError: main


2
你是正确的,运行时正在寻找一个以字符串数组为参数的主方法,并未找到。
你有一个不带字符串数组的主方法并不重要。就像任何其他方法一样,你可以创建多个版本的main(),它们接受不同的参数 - 运行时会忽略它们。

1

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

static void main() {
}

这不是JVM要查找的入口点。

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

因此,main(String[])将被编译器称为main_String_arr,而main()将被称为main。


1

是的..

Java编译器将寻找相同的方法签名来考虑它为main

编写任何具有相同名称但其他参数的函数将导致函数重载..
重载函数并不相同..!!

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

最后,您必须确保您的主要内容如下:

 public static void main(String[] args) 

1

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

public static void main(int foo){}

编译器没有抱怨,因为这是一个有效的方法!只是为了运行Java程序,Java会寻找一个名为“main”的静态方法,并带有一个字符串数组参数。

1
这是来自Java教程/入门的一句话引用:

In the Java programming language, every application must contain a main method whose signature is:

public static void main(String[] args)

The modifiers public and static can be written in either order (public static or static public), but the convention is to use public static as shown above. You can name the argument anything you want, but most programmers choose "args" or "argv".

The main method is similar to the main function in C and C++; it's the entry point for your application and will subsequently invoke all the other methods required by your program.

准确来说,Java将main方法定义为应用程序入口点。并非所有内容都是应用程序,也不是每个main方法都是应用程序入口点。例如,小程序不需要main,因为它使用不同的机制启动。

还要注意自从引入可变参数后,您实际上可以将应用程序入口点声明如下:

 public static void main(String... args)

这是可行的,因为在Java中,变长参数背后的语法糖实际上被实现为数组。

参见

相关问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接