3

我现在正在尝试学习 Java,这是 hello world 程序,它已经开始让我感到困惑。我习惯了 python,我发现教程(电子书)对于具有 python 背景的程序员来说简单而简洁。

本书中的 Java 中的 Hello world 程序:

public class Hello {

public static void main (String[] args) {

     System.out.println("Hello World!");
}
}

正如书中所说,python中的等效代码是:

class Hello(object):
  @staticmethod
  def main(args):
     print "Hello World!"

我完全理解python代码。但是,我对 Java 代码有一个问题,我想在进一步进行之前先弄清楚,以便在我的大脑中获得语言的基本知识。

这本书说(从书中复制):

...我们有一个参数。然而,参数的名称是 args,因为 Java 中的所有内容都必须有一个类型,我们还必须告诉编译器 args 的值是一个字符串数组。目前,您可以将数组视为与 Python 中的列表相同的东西。声明方法 main 必须接受一个参数并且参数必须是字符串数组的实际好处是,如果您在代码中的其他地方调用 main 并将其传递给整数数组甚至单个字符串,编译器会将其标记为错误。

这对我来说没有任何意义。为什么我不能传递任何东西,因为我的函数不需要任何东西?如果我只是通过(String args)会发生什么。

由于我是Java的新手,请多多包涵。

4

8 回答 8

6

好吧,你正在传递一些东西。每当您运行 java 程序时,命令行参数都会作为参数传入args,因此您需要接受这些参数,即使您不使用它们也是如此。

于 2012-04-18T18:05:33.827 回答
4

好吧,这里发生了两件事。首先,是函数签名——因为你声明main期望并只接受一个字符串数组,如果你尝试传递其他东西,它会引发错误。但不是因为函数拒绝接受它,而是因为编译器不知道你要调用什么。看,你可以有多个同名但参数不同的函数。因此,如果您尝试调用main(1),编译器会寻找一个接受一个(或多个)整数的 main 函数,但找不到它并引发异常。

这里发生的另一件事是,当你启动一个程序时,编译器会寻找这个特定的签名——public static void main (String[] args)而不是别的。找不到?程序不会运行。

于 2012-04-18T18:07:13.610 回答
2

如您所知,Python 使用“鸭子类型”:事物是什么类型并不重要,重要的是它可以做什么。因此,您永远不需要为变量声明类型。

在 Java 中,情况并非如此:每个变量都有一个声明的类型,而编译器强制执行该类型。例如,尝试String在 -declared 变量中存储引用int将产生编译时错误。鸭子类型的支持者声称这会降低灵活性,但强类型爱好者指出编译时错误比运行时错误更容易修复。

但是您的方法参数也是如此。因为你的方法需要一个类型的参数String[],所以它必须提供一个类型的参数String[]。没有其他事情会做。

幸运的是,由于它是main方法,Java 解释器负责传入一个参数:具体来说,是一个命令行参数数组,您的程序是使用该数组执行的。如果您想忽略它,请随意。你的程序运行得很好,不用注意参数,但如果没有传入参数,它是无效的。

(顺便说一句,如果这是除了方法之外的任何方法main,您可以使用您想要的任何参数类型自由声明它,包括根本没有参数。但是由于 Java 解释器将传入一个命令行参数,这个特定的方法必须准备好接受它们。)

于 2012-04-18T18:08:55.650 回答
2

在 Java 中,没有像 Python 那样的顶级代码(即没有直接等价于

print('Hello world')

)。然而,Java 程序需要某种入口点才能开始执行代码。与许多其他语言(即 C/C++、C#、Haskell)一样,具有此名称的函数main用于此目的,并由运行时(即 Java 解释器)调用。

调用main函数时,运行时使用一定数量(和类型)的参数。函数必须与这些匹配。然后,您可以随意使用您喜欢的任何签名调用其他方法:

public class Hello {
  public static void hi() {
    System.out.println("Hello World!");
  }
  public static void main (String[] args) {
    hi();
  }
}
于 2012-04-18T18:10:02.673 回答
2

每个程序都有一个入口点/起点,从那里开始执行。Java 会搜索一个特定的方法签名,它将从一个类中开始运行您的应用程序,它是“主要”方法。

public static void main(String args[]);

这必须实施才能让您开始您的程序(在您想要开始的课程中)。由于这个规则/限制,我们必须将字符串数组(类似于 Python 中的字符串列表)作为参数传递。

现在对于第二部分,如果您的程序在启动时不需要任何参数,请不要传递任何参数。您将在 main 方法中将 args 作为空字符串数组。以下行将打印出传递给您的 main 方法的参数长度。

System.out.println("Length of arguments = " + args.length);

您可能还想查看Sun 的 Java 初学者指南。我希望这回答了你的问题。

于 2012-04-18T18:28:02.633 回答
1

如果您的函数不需要任何东西(因此它没有参数),那么您可以避免传递任何东西,这是通过将其声明为

void noArgumentsFunction() {
  // body
}

但是作为main样板的函数必须接受一个Strings 数组。这就是为什么你被迫声明签名接受它(然后忽略它以防万一)。该函数必须接受此参数,因为它是您的程序的入口点,并且任何 Java 程序都必须支持通过命令行传递的参数数组(就像每个 C/C++ 程序一样,如果您不是被迫这样做的话)。

于 2012-04-18T18:06:34.503 回答
1

首先,注意main方法是由JVM调用来启动程序并传递命令行参数的。它可以由 Java 代码调用,但很少这样做。

无论如何,这是该方法的签名:

public static void main (String[] args)

它说它需要一个参数,它是一个字符串数组。如果你这样称呼它:

main(new String[1]); 

或这个:

main(methodThatReturnsAStringArray()); 

它会起作用的。但是这些会导致编译器错误:

main(new int[0]); 
main("test"); 

因为调用中参数的类型与方法签名要求的类型不匹配。您可以传递一个空指针:

main(null); 

因为数组是一种引用类型,并且null是所有引用类型的有效值。但是该方法必须针对这种情况进行测试,否则它会NullPointerException在尝试访问数组时抛出 a 。

您可以做的另一件事是通过声明另一个方法来重载:

public static void main (String args)

所以当你打电话

main("test");

编译器将确定存在具有匹配签名的方法并调用它。

基本上,所有这一切的重点是许多程序员错误是由编译器而不是在运行时捕获的(如果它是一个很少执行的代码路径,它们可能只会在某些特殊情况下被发现)。

于 2012-04-18T18:16:11.507 回答
0

从命令行执行程序时,命令行参数可以是多个字符串。

例如。

Java myprogramme 参数 1 参数 2 参数 3

所有这些参数 - param1、param2、param3 作为字符串 [] 传递。

这对于传递零个、一个或多个参数的所有程序都很常见。

作为程序员,您有责任检查这些命令行参数。

于 2012-04-18T18:08:10.457 回答