java入口函数解析
学习java接触到的第一个程序往往是helloworld。
class Helloworld{
public static void main(String[] args){
System.out.println("Helloworld");
}
}
那么入口函数public static void main(String[] args)是什么意思?它是怎么来的?
String[] args
不难看出,String[] args 是一个字符串数组,用于存储从命令行传递给程序的参数。这些参数在程序启动时被操作系统或者Java运行时环境(JRE)传递给 main 方法。
当你在命令行界面运行一个Java程序时,你通常会使用以下语法:
java YourProgram arg1 arg2 arg3
在这里,YourProgram 是你编译后的Java程序(实际上,它是一个包含 public static void main(String[] args) 方法的Java类),而 arg1、arg2 和 arg3 是你想传递给程序的命令行参数。
这些参数(arg1, arg2, arg3 等)会被放入 String[] args 数组中,然后传递给 main 方法。在 main 方法内,你可以通过索引访问这些参数,比如 args[0] 将会返回 "arg1",args[1] 将会返回 "arg2",依此类推。
这里注意和C语言区分开来
C语言中,
argv[0]为程序名称,argv[1]及后才是参数
下面是一个简单的Java程序示例,演示如何接收和使用命令行参数:
public class CommandLineExample {
public static void main(String[] args) {
System.out.println("你传递了 " + args.length + " 个命令行参数。");
for (int i = 0; i < args.length; i++) {
System.out.println("参数 " + (i + 1) + ": " + args[i]);
}
}
}
如果你将这个程序保存为 CommandLineExample.java,然后通过命令行编译和运行它,你会看到以下效果:
编译:
javac CommandLineExample.java
运行:
java CommandLineExample Hello World 123
输出:
你传递了 3 个命令行参数。
参数 1: Hello
参数 2: World
参数 3: 123
如你所见,在这个例子中,String[] args 数组包含了三个元素:"Hello", "World", 和 "123",这些正是我们从命令行传递给程序的参数。这些参数可以在程序中用于各种目的,比如配置信息、输入文件名、网络地址等。
static
这意味着你不需要创建该类的对象实例就可以调用这个方法。这是有意义的,因为在程序开始运行时,你通常没有对象实例。
如果main()方法没有使用static修饰符,那么编译不会出错,但如果你试图执行该程序将会报错,提示main()方法不存在。因为包含main()的类并没有实例化(即没有这个类的对象)。
如果你很叛逆,非要运行这个程序呢?
办法是有的,既然main()的类并没有实例化,那么实例化这个主类就好了。以下是一个示例。
第一个程序:具有非静态 main 方法的 NonStaticMainExample
public class NonStaticMainExample {
public void main(String[] args) {
System.out.println("这是一个非静态的 main 方法。");
for (int i = 0; i < args.length; i++) {
System.out.println("参数 " + (i + 1) + ": " + args[i]);
}
}
}
第二个程序:创建 NonStaticMainExample 类的实例并调用其 main 方法
public class MainCaller {
public static void main(String[] args) {
// 创建 NonStaticMainExample 类的实例
NonStaticMainExample exampleInstance = new NonStaticMainExample();
// 调用该实例上的非静态 main 方法
String[] newArgs = {"Hello", "World"};
exampleInstance.main(newArgs);
}
}
步骤:
-
将两个程序保存到单独的文件中,分别名为
NonStaticMainExample.java和MainCaller.java。 -
使用
javac编译这两个文件:javac NonStaticMainExample.java MainCaller.java -
运行
MainCaller程序:java MainCaller
当你运行 MainCaller,它将创建一个 NonStaticMainExample 类的实例,并调用该实例上的非静态 main 方法。这将输出:
这是一个非静态的 main 方法。
参数 1: Hello
参数 2: World
实际上,这没有什么意义,因为main已经失去了作为入口函数的功能,它只是该类的一个普通的方法。
public
声明主函数为public就是告诉其他的类可以访问这个函数。这意味着该方法可以从任何其他类或者任何在Java程序中的作用域内被访问。因为Java运行时环境(JRE)需要能够从外部访问这个方法来启动程序,所以它通常需要是 public。
如果你把 public 改为 private 或 protected,那么Java运行时环境将无法访问这个 main 方法,从而无法启动程序。具体来说:
- 把
public改为private:这样做会导致main方法只能在其定义的类内部被访问。Java运行时无法找到一个可访问的入口点,因此会抛出一个运行时错误。 - 把
public改为protected:这样做会使得main方法只能被同一个包内的其他类或该类的子类访问。与private相同,这也会导致Java运行时无法找到一个可访问的入口点。
在某些特殊情况下(例如,当
main方法只用于单元测试或仅在一个更大的应用程序上下文中被调用时),你可能会看到非public的main方法。然而,这样的main方法不能作为一个独立Java程序的入口点。
void
Java程序的标准入口点——main方法——必须返回void。这是Java语言规范的一部分,如果你尝试改变返回类型并作为程序的入口点使用,那么Java运行时环境(JRE)将无法找到有效的入口点。
同static一样,你可以将void改成任何其他类型。它依然能过编译,但没法作为入口函数运行;能在其他类中被调用,但没什么意义。