定义
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,例如
- 方法的名字必须是main
- 方法必须是public static void 类型的
- 方法必须接收一个字符串数组的参数。
案例
// Java中的main()方法详解
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
HelloWorld 类中有main()方法,说明这是个java应用程序,通过JVM直接启动运行的程序。
问题1、main()方法为何被声明为public static?
这和JVM的运行有关系,当一个类中有main()方法,执行命令“java 类名”则会启动虚拟机执行该类中的main方法。由于JVM在运行这个Java应用程序的时候,首先会调用main方法,调用时不实例化这个类的对象,而是通过类名直接调用,因此需要是限制为public static。
此外对于java中的main方法,jvm有限制,不能有返回值,因此返回值类型为void。
、
问题2、main()方法入参
main方法中还有一个输入参数,类型为String[],这个也是java的规范,main()方法中必须有一个入参,类细必须String[],至于字符串数组的名字,这个是可以自己设定的,根据习惯,这个字符串数组的名字一般和sun java规范范例中mian参数名保持一致,取名为args。
public class NewTest {
public static void main(String args[]){
for(int i = 0;i < args.length; i++){
System.out.println("prinit:" +args[i]);
}
}
}
在idea运行main方法,会发现打印参数为空,原因是idea中启动这个类默认传空参
javac NewTest.java #编译NewTest这个java文件
java NewTest 1,2,3 #运行NewTest的.class文件
结果
main()方法中可以throw Exception
public class TestMain {
public static void main(String\[\] args) throws Exception {
System.out.println("111");
throw new Exception("");
}
}
@Test单测方法和main方法区别
单测方法结束的时候会把里面的资源释放了,导致里面线程提前结束。main方法结束后其它的线程资源还能继续运行,案例如下,这是一个模拟ConcurrentModificationException异常的案例
main方法中会产生预期的报错
public static void main(String[] args) {
Map<String,String> list = new HashMap<>();
for (int i = 0; i < 30
; i++) {
new Thread(()->{
list.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},"t"+i).start();
System.out.println(i);
}
}
test方法中不会出现预期报错
@Test
public void test() throws InterruptedException {
Map<String,String> list = new HashMap<>();
for (int i = 0; i < 30
; i++) {
new Thread(()->{
list.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},"t"+i).start();
}
}
test方法中对应test线程,因为for循环中每次循环都会创建一个新线程并立刻启动了该线程,test线程进行for循环30次是个瞬时操作(1ms以内完成),而线程的创建+启动个人主机需要几百毫秒,没等线程的创建+启动,test线程就执行完了,而其余30个线程只能是释放资源然后方法结束;
所以,我们让test线程睡1000ms,给其它线程创建和运行的时间,这样就能复现这个exception了
@Test
public void test() throws InterruptedException {
Map<String,String> list = new HashMap<>();
for (int i = 0; i < 30
; i++) {
new Thread(()->{
list.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},"t"+i).start();
System.out.println(111);
}
Thread.sleep(1000);
}
结论:多线程测试不要在test测试方法中进行,需要在main中进行