2018-03-18

Java基础类库-与用户互动

1. 与用户互动

1.1 运行Java程序的参数

Java程序的入口——main()方法的方法签名:

//Java程序入口:main()方法
public static void main(String[] args){....}

mian方法为什么采用这个方法签名?

  • public修饰符:java类是有JVM调用,为了让JVM能够自动调用这个main()方法,因此使用public修饰符将这个方法暴露出来;
  • static修饰符:当JVM调用这个主方法时,并不会创建该主类的对象,然后通过对象来调用该主方法。而是直接通过该类来调用这个主方法,因此使用static修饰该主方法;
  • void修饰符:由于主方法被JVM调用,该方法的返回值将返回给JVM,这是没有任何意义,因此main()方法没有返回值;
  • String[] args:字符串数组形参,根据方法调用规则——谁调用方法,谁就负责为形参赋值,就是说,main()方法有JVM调用,即args形参应该由JVM赋值赋值libraries
    那么问题来了,JVM怎么知道如何为args数组赋值呢?看下面的程序:
//:classlibraries/ArgsTest.java
public class ArgsTest {
  public static void main(String[] args){
    //输出args数组的长度
    System.out.println(args.length);
    //遍历输出args数组的诶一个程序
    for(String arg : args){  
      System.out.println(arg);
    }
  }
}/*output
0
*///:~

上面程序几乎是最简单的“Hello World”程序,只不过这个程序增加了输出args的长度,遍历args数组元素的代码。当使用java ArgsTest命令运行上面程序的时候,可以看到程序仅仅输出一个0,这表明args数组是一个长度为0的数组——这个合理的,因为计算机是没有思考的能力,它(计算机)只能忠实地执行用户交给它的任务,既然程序没有给args数组设定参数值,那么JVM就不知到args数组的元素,于是JVM将args数组设置成一个长度为0的数组。然而将java ArgsTest命令修改为如下:

java ArgsTest Java Spring SpringMVC
/*output
2
Java
Spring
SpringMVC
*///:~

由此可知:如果在运行Java程序的时候在类名后紧跟一个或多个字符串(多个字符串之间以空格隔开),JVM就会把这些字符串依次赋给args数组元素。
!如果某参数本身包含了空格,则应该将该参数用双引号(“”)括起来,否则JVM会把这个空格当成参数分隔符,而不是参数本身,如下:

java ArgsTest "Hello World"
/*output
1
Hello World
*///:~

1.2 使用Scanner获取键盘输入

使用Scanner类可以获取用户的键盘输入。
Scanner是基于正则表达式的文本扫描器
它可以从文件、输入流、字符串中解析出基本类型值和字符串值。这个类提供了多个构造器,不同的构造器通过接受不同参数(文件、输入流和字符串作为数据源),用于从中解析数据。
Scanner主要提供了两种方法来扫描输入:

  • hasNextXxxx():判断是否还有下一个输入项,其中Xxx代表基本数据类型的字符串。如果只是判断是否含下一个字符串,则直接使用hasNext()。
  • nextXxx():获取下一个输入项。Xxx的含义同上。
    默认情况下,Scanner使用空白(包括空格、Tab空白、回车)作为多个输入项之间的分隔符。
    下面程序使用Scanner来获得用户的键盘输入:
//:classlibraries/ScannerKeyBoardTest.java
import java.util.Scanner;
public class ScannerKeyBoardTest {
    public static void main(String[] args){
        //System.in代表标准输入,就是键盘输入
        System.out.println("请输入:");
        Scanner scanner = new Scanner(System.in);
        //增加下面一行将只把回车作为分隔符
        //scanner.useDelimiter("\n");
        //判断是否还有下一项
        while(scanner.hasNext()){
            //输出输入项
            System.out.println("键盘输入的内容是:"+scanner.next());
        }   
    }
}/*
Spring
键盘输入的内容是:Spring
Mybatis
键盘输入的内容是:Mybatis
SpringMVC
键盘输入的内容是:Spring MVC
*///:~

Scanner的读取操作可能被阻塞(当前的执行顺序流暂停),等待信息的输入。如果输入源没有结束,Scanner又读不到更多输入项的时候(尤其在键盘输入时比较常见),hasNext()和next()方法都有可能,hasNext()方法是否阻塞与和其相关的next()方法是否阻塞无关!!!
Scanner提供了连个简单的方法来逐行读取!!!

  • boolean hasNextLine(); 返回输入源中是否还有下一行;
  • String nextLine(); 返回输入源中下一行的字符串
//:classlibraties/ScannerLongTest.java
public class ScannerLongTest{
  public static void main(String[] args){
    //System.in代表标准输入(键盘输入)
    Scanner sc = new Scanner(System.in);
    //判断是否还有下一个long型整数
    while(sc.hasNextLong()){
      //输出输入项
      System.out.println("键盘输入的内容是:");
    }
  }
}/*output
11111
键盘输入的内容是:11111
*///~

上面的代码,是通过hasNextLong()和nextLong()两个方法,Scanner可以直接从输入流中获得long型整数输入项。与此类似的是:如果需要获取其他基本类型的输入项,则可以使用对应的方法。
但是,上面的程序不如ScannerKeyBoardTest程序的适应性强,因为ScannerLongTest程序要求键盘输入的必须是整数。否则程序就会退出。
当然,Scanner还可以读取文件输入。只要在创建Scanner对象时传入一个File对象作为参数,就可以让Scanner读取该文件的内容。

//:classlibarties/ScannerLongTest.java
import java.io.IOException;
import java.util.Scanner;
import java.io.File;
public class ScannerFileTest {
    public static void main(String[] args) throws IOException {
        //实例化一个Scanner对象
        File scannerFile = new File("scanner_file.txt");
        //将File对象作为scanner的构造器参数,Scanner读取文件内容
        Scanner scanner = new Scanner(scannerFile);
        //判断是否有下一行
        while(scanner.hasNextLine()){
            //输出文件中的下一行
            System.out.println(scanner.nextLine());
        }
    }
}/*output
here is scanner_file.txt!!!
*///~

你可能感兴趣的:(2018-03-18)