常用类之System、Scanner
1.System
System类定义了一些和系统相关的属性和方法。
public final class System
extends Object
System为final修饰的类,不能被继承。
System类中有三个静态变量:
static PrintStream err "标准"错误输出流
static InputStream in "标准"输入流(该流对应于键盘输入或由主机环境或用户指定的另一个输入源)
static PrintStream out "标准"输出流(此流对应于显示输出或由主机环境或用户指定的另一个输出目标)
最常用的当属System.out.println();
了!
System中的方法都为静态方法,可直接使用System调用。
其中常用的为exit(),gc(),currentTimeMillis()
package com.dh.system;
public class SystemDemo {
public static void main(String[] args) {
//获取当前时间
long time1 = System.currentTimeMillis();
System.out.println("程序运行开始时间:"+time1+"ms");
//垃圾回收
System.gc();
//再次获取当前时间
long time2 = System.currentTimeMillis();
System.out.println("程序运行结束时间:"+time2+"ms");
//计算垃圾回收运行的时间
System.out.println("程序运行所耗时间:"+(time2 - time1)+"ms");
//退出程序,0表示正常结束,非0表示异常结束
System.exit(0);
//因为上述已经退出了,所以不会执行该语句
System.out.println("11111111");
}
}
结果:
程序运行开始时间:1611382838721ms
程序运行结束时间:1611382838750ms
程序运行所耗时间:29ms
Process finished with exit code 0
2.Scanner
用于接收从键盘中输入的数据。之前写的程序都是程序输出结果,有了Scanner我们也可以向程序输入数据,就可以与程序有简单的交互了。
有10种构造方法,最常用的是:
Scanner(InputStream source) //构造一个新的 Scanner ,产生从指定输入流扫描的值
我们可以看到,所需的参数是InputStream类型的,我们刚刚讲到的System类中就有一个静态变量in为InputStream类型的,没错,我们使用的就是System中的in。
(1)Scanner接收基本数据类型数据
实例化对象后,我们就可以使用Scanner类里的方法了,先使用nextXXX()方法看看能不能接收数据:
注意:nextXXX,XXX为数据类型,并且该方法会阻塞程序,必须输入数据之后按回车才可以继续运行程序。
以下例子都使用int数据类型,其余7种基本数据类型同。
package com.dh.Scanner;
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
//实例化一个Scanner对象
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数:");
//接收int类型的数据
int num = scanner.nextInt(); //在这里程序会阻塞,必须要输入数据才会继续往下执行
//输出刚刚接收到的键盘输入的数据
System.out.println("接收到的数据为:"+num);
}
}
结果:
请输入一个整数:10
接收到的数据为:10
如果我们不小心输错了呢,想要的是个整数,但是不小心输入了一个字符,会怎么样呢?
结果:
请输入一个整数:abc
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at com.dh.Scanner.ScannerDemo.main(ScannerDemo.java:13)
Process finished with exit code 1
当输入的类型不匹配时,程序就会抛出InputMismatchException异常,即输入不匹配异常。
你肯定会说,那很简单啊,我们只要判断一下输入的数据和我们所需要的数据类型是否匹配不就好了吗?没错,就是这样解决的,Scanner类也给我们提供了判断输入数据与所需数据类型是否匹配的方法,hasNextXXX,XXX为具体的数据类型:
package com.dh.Scanner;
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
//实例化一个Scanner对象
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数:");
//判断输入的数据类型和所需的是否匹配
if(scanner.hasNextInt()){
//匹配
//接收int类型的数据
int num = scanner.nextInt(); //在这里程序会阻塞,必须要输入数据才会继续往下执行
//输出刚刚接收到的键盘输入的数据
System.out.println("接收到的数据为:"+num);
}else{
//不匹配
System.out.println("输入数据不合法!");
}
}
}
结果:
请输入一个整数:abc
输入数据不合法!
Process finished with exit code 0
使用hasNextXXX()判断输入数据与所需数据类型是否一致,这样就能避免输入数据不匹配造成的异常情况了。
(2)Scanner接收字符串
Scanner接收字符串有两种方法,一种是next(),一种是nextLine(),通过例子来看看它们有什么不一样:
-
next()
package com.dh.Scanner; import java.util.Scanner; public class ScannerString { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入您想输入的字符串:"); //因为输入的任何数据都可以是字符串,故不需要数据类型匹配判断 String s = scanner.next(); System.out.println("您输入的字符串为:"+s); } }
结果:
请输入您想输入的字符串: gsj jah jk 您输入的字符串为:gsj Process finished with exit code 0
我们通过结果观察到:next()接收字符串,会忽略掉第一个有效字符前的回车、空格、tab;碰到有效字符后的回车键输入结束,碰到有效字符后的空格和tab之后的内容也都会忽略。
-
nextLine()
package com.dh.Scanner; import java.util.Scanner; public class ScannerString { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入您想输入的字符串:"); //因为输入的任何数据都可以是字符串,故不需要数据类型匹配判断 String s = scanner.nextLine(); System.out.println("您输入的字符串为:"+s); } }
一开始就输入回车:
请输入您想输入的字符串: 您输入的字符串为: Process finished with exit code 0
请输入您想输入的字符串: asd jjj e 您输入的字符串为: asd jjj e Process finished with exit code 0
通过观察,nextLine()接收字符串,一遇到回车就结束输入;会保留空格、tab键。
(3)基本数据类型与字符串交替输入问题
-
先接收String类型,再接收int类型:不存在问题。
package com.dh.Scanner; import java.util.Scanner; public class ScannerDemo2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //字符串 System.out.print("请输入一个字符串:"); String s = scanner.nextLine(); //整数,暂时不考虑输入类型匹配问题 System.out.print("请输入一个整数:"); int num = scanner.nextInt(); System.out.println("字符串:"+s); System.out.println("整数:"+num); } }
结果:
请输入一个字符串:abc 请输入一个整数:3 字符串:abc 整数:3 Process finished with exit code 0
-
先接收int类型,再接收String类型:存在问题。
请输入一个整数:3 请输入一个字符串:整数:3 字符串: Process finished with exit code 0
可以看到此时出现问题了,还没来得及输入字符串就已经输出了结果,并且此时的字符串也是为''的。
分析:因为nextLine是碰到回车就会结束数据的输入的,所以在输入第一个int数据时,检测到了回车,就当作已经结束输入数据而结束了。
那我们刚刚说next()会忽略一开始的回车,那我们可不可以将nextLine()改成next()来解决问题呢?
与上述测试代码一致,只是将nextLine(),替换成了next()。
结果:
请输入一个整数:3 请输入一个字符串:abc 整数:3 字符串:abc Process finished with exit code 0
此时是没有问题的,但是我们知道如果输入数据有空格、tab键、回车,是又可能丢失数据的。
那我们能不能还是用nextLine(),但是也不会出现上述的问题呢?
也是可以的,只要我们再创建一个Scanner对象用于接收字符串就可以了!
package com.dh.Scanner; import java.util.Scanner; public class ScannerDemo2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //整数,暂时不考虑输入类型匹配问题 System.out.print("请输入一个整数:"); int num = scanner.nextInt(); //字符串 //再创建一个Scanner对象用于接收字符串 Scanner scanner1 = new Scanner(System.in); System.out.print("请输入一个字符串:"); String s = scanner1.nextLine(); System.out.println("整数:"+num); System.out.println("字符串:"+s); } }
结果:
请输入一个整数:4 请输入一个字符串: hello world 整数:4 字符串: hello world Process finished with exit code 0