为什么Java中的main方法总是需要参数?

为什么Java中的主要方法总是需要参数? 为什么我们每次都要写String[] args ,而不是在使用任何参数的时候写出来呢?

像这样的方法生成Main method not found编译器错误。 由于我们从来没有使用任何主要方法的参数,这应该是允许的。

 public static void main() { } 

这不是一个面试问题。 编程时,我才想起它。

基本上有四个答案:

  1. 因为这是它的devise方式。 是的,我知道这是一个循环的原因。 但重要的是,这是它的方式,它不会改变。 所以除非你打算devise自己的语言,否则这个问题是没有意义的。

  2. devise的清洁(也就是DRY原则)。 当可以完成工作时,不要指定两个入口点签名。 显然,它可以。

  3. 语义简单。 假设(假设)Java 确实同时支持void main(String[])void main()入口点。 如果一个类定义了两种方法会发生什么? 这是一个错误? 如果不是,哪一个在歧义时优先? 这是否令人困惑?

    通过只允许void main(String[]) ,JLS避免了这个问题。

  4. 这类似于标准的C和C ++入口点签名。 (不可否认,一些C / C ++运行时支持其他非标准的入口点,但是这不是一件好事… IMO。)

这一切都不意味着以另一种方式做这件事是毫无疑问的错误。 例如,C#为您提供了替代签名,并通过要求开发人员以其他方式指定入口点来解决模糊性问题。

FWIW, 这个维基百科页面描述了一些语言的“主要”方法。

因为运行应用程序的java工具查找具有特定签名的main ,所以它知道它正在调用正确的签名。 Java有方法重载,因此在查找方法时,必须指定一个相当完整的签名。 授予java工具可以做更复杂的事情(寻找特定的签名,而没有find它,寻找任何main ,如果它只能find一个),但这不是Javadevise师决定( 主观上 , FWIW,我认为这是最好的 – 保持简单)。

您可以在Java语言规范第12章:执行中find详细信息。 并且注意到,当Java获得可变参数列表时,有可能以两种不同的方式声明main

 public static void main(String[] args) // or public static void main(String... args) 

当JVM开始执行java程序时,它会search具有此签名的主要方法(即string数组)

这是因为规范

参数有助于将parameter passing给主程序


看到

  • 命令行参数

这只是他们devise的方式。 推论到这一点,你可能会问为什么它的表兄弟(C#)允许有或没有参数的Main方法,这只是他们devise它的方式。

那里没有严肃的理由,每个语言devise者都有他们的偏好,你应该遵循什么原则。 有时候,这对我们来说是推断,或者坚持(有时候我们无法按照自己的方式)。

嗯…这让我想起我现在使用的操作系统。 在OS X Lion之前,您只能调整窗口右下angular的大小。 在他们终于把能力调整到他们操作系统的任何窗口的angular度之前,这已经有28年多的时间了。

即使我太喜欢Mac OS了,我也不会出去捍卫自己的立场,只能在一个angular落调整一个窗口。 狂热是一回事,但盲目坚持是另一回事。

所以,你正在练习批判性思维是好事,而不是盲目地相信Java的主要方法签名是唯一正确的方法


一个离题,等待Mac在任何angular落都有可调整的边缘,就像我在等待Java拥有一stream的财产。 尽pipeJSON名称( Java脚本对象表示法,尽pipeJavascript不是Java),但与使用JSON的Java对象初始化程序相比,C#对象初始值设定项(通过其属性初始值设定项和集合初始值设定项)与JSON更具亲和力。 C#对象初始化器非常整齐,非常类似于JSON。

C#

 var p = new { Lastname = "Lennon", Firstname = "John", PlacesBeen = new[] { new { City = "Liverpool", Country = "England" }, new { City = "New York", Country = "US" }, new { City = "Tokyo", Country = "Japan" } } }; return Json(p); 

使用Javascript:

 var p = { "Lastname" : "Lennon", "Firstname" : "John", "PlacesBeen" : [ { "City" : "Liverpool", "Country" : "England" }, { "City" : "New York", "Country" : "US" }, { "City" : "Tokyo", "Country" : "Japan" } ] }; 

因此,使用C#的第一类属性(不是绑定到方法)和集合初始化程序,不仅代码变得简洁而且整洁,现在它与现在大多数开发人员正在使用的数据交换格式(即JSON)非常相似。

Java的对象初始化程序语法远不是JSON风格。 在这方面,我不会捍卫Java的devise决定(例如属性语法/devise):-)

所以在这里,我不会捍卫Java语言devise者对Java属性语法/devise的devise决定,我不会捍卫public static void main(String[] args)

当你试图运行一个java程序时,JVM将会以String数组作为参数来searchmain方法,从那里开始执行程序。 由于您提供的方法不与该签名,所以它会引发一个exception找不到主要的方法

我认为Java从c / c ++“复制”了这个习惯,并且在java.c中用硬编码:

  /* Get the application's main method */ mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); if (mainID == NULL) { if ((*env)->ExceptionOccurred(env)) { ReportExceptionDescription(env); } else { message = "No main method found in specified class."; messageDest = JNI_TRUE; } goto leave; } 

java是这样devise的。 如果我们不写stringargs [],那么程序将被编译,但不会运行。

它可能是因为大部分的input来自main()之外,就像命令行参数一样,所以为了捕获这些值,它有String [] args签名。