这些Java教程是为JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及以后版本的更新语言特性的摘要。
请参阅JDK发布说明,了解所有JDK版本的新功能、增强功能和删除或弃用选项的信息。
程序通常从命令行运行,并在命令行环境中与用户交互。Java平台通过两种方式支持这种交互:标准流和控制台。
标准流是许多操作系统的特性。默认情况下,它们从键盘读取输入并将输出写入显示器。它们还支持文件和程序之间的输入/输出,但该特性由命令行解释器控制,而不是程序本身。
Java平台支持三种标准流:标准输入(通过System.in访问)、标准输出(通过System.out访问)和标准错误(通过System.err访问)。这些对象是自动定义的,不需要打开。标准输出和标准错误都是用于输出;将错误输出分开可以使用户将常规输出重定向到文件,并仍然能够读取错误消息。有关更多信息,请参阅您的命令行解释器的文档。
您可能期望标准流是字符流,但出于历史原因,它们是字节流。System.out和System.err被定义为PrintStream对象。虽然它在技术上是字节流,但PrintStream利用一个内部字符流对象来模拟许多字符流的功能。
相比之下,System.in是一个没有字符流功能的字节流。要将标准输入用作字符流,可以将System.in包装在InputStreamReader中。
InputStreamReader cin = new InputStreamReader(System.in);
标准流的更高级替代方案是控制台。这是一种预定义的Console类型的对象,具有标准流提供的大部分功能,以及其他功能。控制台在安全密码输入方面特别有用。控制台对象还通过其reader和writer方法提供真正的字符流的输入和输出流。
在程序使用控制台之前,必须尝试通过调用System.console()来检索控制台对象。如果控制台对象可用,此方法将返回它。如果System.console返回NULL,则不允许使用控制台操作,这可能是因为操作系统不支持它们,或者因为在非交互式环境中启动了程序。
控制台对象通过其readPassword方法支持安全密码输入。该方法通过两种方式帮助确保密码安全输入。首先,它禁止回显,因此密码在用户屏幕上不可见。其次,readPassword返回一个字符数组,而不是String,因此可以覆盖密码,一旦不再需要,即可从内存中删除它。
这个示例是一个用于更改用户密码的原型程序。它演示了几个Console方法。
import java.io.Console;
import java.util.Arrays;
import java.io.IOException;
public class Password {
public static void main (String args[]) throws IOException {
Console c = System.console();
if (c == null) {
System.err.println("没有控制台。");
System.exit(1);
}
String login = c.readLine("请输入您的登录名:");
char [] oldPassword = c.readPassword("请输入您的旧密码:");
if (verify(login, oldPassword)) {
boolean noMatch;
do {
char [] newPassword1 = c.readPassword("请输入您的新密码:");
char [] newPassword2 = c.readPassword("请再次输入新密码:");
noMatch = ! Arrays.equals(newPassword1, newPassword2);
if (noMatch) {
c.format("密码不匹配,请重试。%n");
} else {
change(login, newPassword1);
c.format("%s的密码已更改。%n", login);
}
Arrays.fill(newPassword1, ' ');
Arrays.fill(newPassword2, ' ');
} while (noMatch);
}
Arrays.fill(oldPassword, ' ');
}
// 虚拟的验证方法。
static boolean verify(String login, char[] password) {
// 在这个示例中,这个方法总是返回true。
// 根据您的规则修改此方法以验证密码。
return true;
}
// 虚拟的更改方法。
static void change(String login, char[] password) {
// 根据您的规则修改此方法以更改密码。
}
}
Password类遵循以下步骤:
Console.readLine提示并读取用户的登录名。Console.readPassword提示并读取用户的现有密码。verify确认用户是否有权更改密码。(在这个示例中,verify是一个虚拟方法,总是返回true。)Console.readPassword两次提示并读取新密码。change来更改密码。(同样,change是一个虚拟方法。)