相信很多人在刚开始学习java的时候,使用的第一个语句就是System.out.println("hello world");那时候我们也没多想,照着书上打,然后就奇迹般的在我们机器的显示器上显示了“hello world”,虽然很简单,但是也让我们高兴了好久,自己终于会用java了。。。
然而,或许到现在我们也没有理会System.out到底是什么。其实System.out是java提供的标准输出流,它已经事先被包装成了PrintStream对象,也就是说System.out本质就是PrintStream,这一点我们通过看System类的源码便知。
public final class System {
// ...省略其它源码
public final static PrintStream out = null;
}
既然System.out就是PrintStream,那么我们就完全可以像使用PrintStream一样使用System.out。
package com.gk.io.byte_;
import java.io.PrintStream;
import java.io.PrintWriter;
public class StandardStreamDemo {
public static void main(String[] args) {
out();
}
public static void out() {
PrintStream ps = System.out;
ps.println(47); // 往控制台输出int类型数据
ps.println(13.14); // 往控制台输出double类型数据
ps.println("I love java"); // 往控制台输出string类型数据
}
}
由于System.out是一个PrintStream,而PrintStream是一个OutputStream,也就是说System.out是一个字节流。为了使用起来更加高效快捷,我们完全可以将System.out包装成PrintWriter。
public static void out2() {
PrintWriter pw = new PrintWriter(System.out, true);
pw.println(47); // 往控制台输出int类型数据
pw.println(13.14); // 往控制台输出double类型数据
pw.println("I love java"); // 往控制台输出string类型数据
}
使用带有两个参数的PrintWriter构造器,第二个参数设置为true表示开启自动刷新,否则,可能由于输出的数据小于缓冲区的大小而导致数据暂时存放于缓冲区中,从而看不到数据的输出。
System类还有另一个常量in,它就是java提供的标准输入流,不过System.in却是一个没有被包装过的未经加工的InputStream,也就是说在使用System.in之前必须对其进行包装。
通常我们会用readLine()一次一行的读取输入,所以我们可以将System.in包装成BufferedReader,从而实现从控制台的输入。
public static void in() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入一个整数 : " );
int integer = Integer.parseInt(br.readLine());
System.out.println("您输入的整数是 : " + integer);
System.out.println();
System.out.print("请输入一个小数 : " );
double decimal = Double.parseDouble(br.readLine());
System.out.println("您输入的小数是 : " + decimal);
System.out.println();
System.out.print("请输入一个字符串:");
String line = br.readLine();
System.out.println("您输入的字符串是 : " + line);
// 释放资源
br.close();
}
上面方法虽然也能实现从控制台输入任意类型数据,但是比较麻烦,需要我们自己将字符串解析成任意类型数据,也可能会出现NumberFormatException异常,所以一般我们不这样用。JDK1.5给我们提供了Scanner,我们可以很方便的使用Scanner从控制台输入任意类型数据。
public static void in2() throws IOException {
Scanner sc = new Scanner(System.in);
System.out.print("请输入一个整数 : " );
int integer = sc.nextInt();
System.out.println("您输入的整数是 : " + integer);
System.out.println();
System.out.print("请输入一个小数 : " );
double decimal = sc.nextDouble();
System.out.println("您输入的小数是 : " + decimal);
System.out.println();
System.out.print("请输入一个字符串:");
sc.nextLine();
String line = sc.nextLine();
System.out.println("您输入的字符串是 : " + line);
System.out.println();
// 释放资源
sc.close();
}
Scanner提供了两个方法next()和nextLine()用于输入字符串。两者的区别如下:
next()方法一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键、tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后输入的空格键、tab键或Enter键等视为分隔符或结束符。
而nextLine()方法的结束符只是Enter键,即nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。
由于nextLine()可以得到带空格的字符串,所以我们选择用nextLine()方法输入“I love java”,又由于nextLine()遇到Enter键就结束,所以在使用nextLine()时先在前面再使用一次nextLine()以过滤掉nextDouble()后的Enter键。如果nextLine()为第一个输入则不需要这样做。