为什么Java中的main方法总是需要参数?为什么我们每次都要写String[] args
,而不是在我们使用任何参数时写它?
这样的方法会生成Main method not found
编译器错误。因为我们从不对main方法使用任何参数,所以应该允许这样做。
public static void main()
{
}
这不是面试问题。编程时我才想到它。
答案 0 :(得分:31)
基本上,有四个答案:
因为这就是它的设计方式。是的,我知道这是一个循环的原因。但重点是,这是它的方式,它不会改变。因此,除非您计划设计自己的语言,否则这个问题没有实际意义。
设计的清洁度(又名DRY原则)。当一个人可以完成工作时,不要指定两个入口点签名。显然,它可以。
语义简洁。假设(假设)Java 支持void main(String[])
和void main()
入口点。如果一个类定义了两个方法会发生什么?这是一个错误吗?如果没有,当存在歧义时哪一个优先?这有点令人困惑吗?
仅允许void main(String[])
,JLS可以避免此问题。
这类似于标准C和C ++入口点签名。 (不可否认,一些C / C ++运行时也支持其他非标准入口点......但这并不是一件好事...... IMO。)
这些都不意味着以另一种方式做到这一点毫无疑问是错误的。例如,C#为您提供了替代签名,并通过要求开发人员以其他方式指定入口点来处理歧义问题。
FWIW,this wikipedia page描述了多种语言的“主要”方法。
答案 1 :(得分:5)
因为运行应用程序的java
工具会查找具有特定签名的main
,所以它知道它正在调用正确的签名。 Java有方法重载,因此在查找方法时,您必须指定相当完整的签名。当然,java
工具可以做一些更复杂的事情(寻找特定的签名,找不到它,寻找任何main
并调用它,如果它只发现一个),但这不是Java设计师决定这样做(而主观,FWIW,我认为这是最好的 - 保持简单)。
您可以在Java语言规范Chapter 12: Execution中找到详细信息。请注意,当Java获得可变参数列表时,可以通过两种不同的方式声明main
:
public static void main(String[] args)
// or
public static void main(String... args)
答案 2 :(得分:0)
当JVM开始执行java程序时,它会搜索具有此签名的主方法(即字符串数组)
答案 3 :(得分:0)
这就是他们设计它的方式。因此,您可能会问为什么它的堂兄(C#)允许带有或不带参数的Main方法,这就是他们设计它的方式。
那里没有严肃的理由,每个语言设计师都有自己的偏好,你应该订阅哪些原则。有时我们会在此期间推断或坚持(有时我们无法按照自己的方式行事)。
嗯......这让我想起了我现在正在使用的操作系统。在OS X Lion之前,您只能在窗口的右下角调整大小。这是28年以上的等待之后,他们最终将能力调整到操作系统的任何窗口角落。即使我太喜欢Mac OS,我也不会出去捍卫他们的立场,因为窗口应该只在一个角落调整大小。狂热是一回事,但盲目坚持是另一回事。
所以你正在练习批判性思维而不是盲目相信Java的主要方法签名是唯一正确的方法
<小时/> 一个题外话,等待Mac在任何角落都有可调整边缘,这类似于我等待Java拥有一流的财产。尽管有JSON名称( Java 脚本对象表示法,当然Javascript不是Java),但与Java对象初始化程序相比,C#对象初始化程序(通过其属性初始化程序和集合初始化程序)与JSON具有更强的亲和性。 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的设计决策(例如属性语法/设计): - )
所以,在同样的情况下,我不会捍卫Java语言设计者关于Java属性语法/设计的设计决定,我不会捍卫public static void main(String[] args)
ツ
答案 4 :(得分:-1)
当您尝试运行java程序时,JVM将使用 String array 作为参数搜索main方法,以从那里开始执行程序。由于您给出的方法不是该签名,因此会引发异常找不到主要方法
答案 5 :(得分:-1)
我认为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;
}
答案 6 :(得分:-1)
java就是这样设计的。如果我们不编写字符串args [],那么程序将被编译 但它不会运行。
答案 7 :(得分:-1)
它可能是因为大多数输入来自main()之外,如命令行参数,所以为了捕获这些值,它有String [] args signature。