Quick Guide to java.lang.System – java.lang.System快速指南

最后修改: 2018年 4月 12日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll take a quick look at the java.lang.System class and its features and core functionality.

在本教程中,我们将快速浏览一下java.lang.System类及其特点和核心功能。

2. IO

2.IO

System is a part of java.lang, and one of its main features is to give us access to the standard I/O streams.

Systemjava.lang的一部分,其主要功能之一是让我们访问标准I/O流。

Simply put, it exposes three fields, one for each stream:

简单地说,它暴露了三个字段,每个流都有一个。

  • out
  • err
  • in

2.1. System.out

2.1.System.out

System.out points to the standard output stream, exposing it as a PrintStream, and we can use it to print text to the console:

System.out指向标准输出流,将其作为PrintStream公开,我们可以用它来打印文本到控制台。

System.out.print("some inline message");

An advanced usage of System is to call System.setOut, which we can use to customize the location to which System.out will write:

System的一个高级用法是调用System.setOut,我们可以用它来定制System.out将写入的位置。

// Redirect to a text file
System.setOut(new PrintStream("filename.txt"));

2.2. System.err

2.2. System.err

System.err is a lot like System.out. Both fields are instances of PrintStream, and both are for printing messages to the console.

System.err很像System.out。这两个字段都是PrintStream的实例,而且都是用于向控制台打印消息。

But System.err represents standard error and we use that specifically to output error messages:

System.err代表标准错误,我们专门用它来输出错误信息。

System.err.print("some inline error message");

Consoles will often render the error stream differently than the output stream.

控制台通常会以不同于输出流的方式渲染错误流。

For more information, check the PrintStream documentation.

欲了解更多信息,请查看PrintStream 文档。

2.3. System.in

2.3.System.in

System.in points to the standard in, exposing it as an InputStream, and we can use it for reading input from the console.

System.in指向标准in,将其暴露为InputStream,我们可以用它来读取控制台的输入。

And while a bit more involved, we can still manage:

虽然涉及的内容更多一些,但我们仍然可以做到。

public String readUsername(int length) throws IOException {
    byte[] name = new byte[length];
    System.in.read(name, 0, length); // by default, from the console
    return new String(name);
}

By calling System.in.read, the application stops and waits for input from the standard in. Whatever the next length bytes are will be read from the stream and stored in the byte array.

通过调用System.in.read,应用程序停止并等待来自标准输入的输入。不管下一个长度字节是多少,都将从流中读取并存储在字节数组中。

Anything else typed by the user stays in the stream, waiting for another call to read.

用户输入的其他任何东西都留在流中,等待对read.的再次调用。

Of course, operating at that low of a level can be challenging and error-prone, so we can clean it up a bit with BufferedReader:

当然,在这么低的水平上操作可能是有难度的,而且容易出错,所以我们可以用BufferedReader把它清理一下。

public String readUsername() throws IOException {
    BufferedReader reader = new BufferedReader(
      new InputStreamReader(System.in));
    return reader.readLine();
}

With the above arrangement, readLine will read from System.in until the user hits return, which is a bit closer to what we might expect.

通过上述安排,readLine将从System.in中读取,直到用户点击返回,这有点接近我们可能期望的情况。

Note that we purposely don’t close the stream in this case. Closing the standard in means that it cannot be read again for the lifecycle of the program!

请注意,在这种情况下,我们特意没有关闭流。关闭标准的in意味着在程序的生命周期内不能再被读取!

And finally, an advanced usage of System.in is to call System.setIn to redirect it to a different InputStream.

最后,System.in的高级用法是调用System.setIn,将其重定向到不同的InputStream

3. Utility Methods

3.实用方法

System provides us with numerous methods to help us with things like:

系统为我们提供了许多方法来帮助我们处理一些事情。

  • Accessing the console
  • Copying arrays
  • Observing date and time
  • Exiting the JRE
  • Accessing runtime properties
  • Accessing environment variables, and
  • Administering garbage collection

3.1. Accessing the Console

3.1.访问控制台

Java 1.6 introduced another way of interacting with the console than simply using System.out and in directly.

Java 1.6引入了另一种与控制台互动的方式,而不是简单地直接使用System.outin

We can access it by calling System.console:

我们可以通过调用System.console来访问它。

public String readUsername() {
    Console console = System.console();	 	 
	 	 
    return console == null ? null :	 
      console.readLine("%s", "Enter your name: ");	 	 
}

Note that depending upon the underlying operating system and how we launch Java to run the current program, console might return null, so always make sure to check before using.

请注意,根据底层操作系统和我们启动Java运行当前程序的方式,console可能会返回null,所以在使用前一定要检查

Check out the Console documentation for more uses.

请查看控制台文档以了解更多的用途。

3.2. Copying Arrays

3.2.复制数组

System.arraycopy is an old C-style way of copying one array into another.

System.arraycopy是一种古老的C语言方式,将一个数组复制到另一个数组中。

Mostly, arraycopy is intended to copy one complete array into another array:

大多数情况下,arraycopy的目的是将一个完整的数组复制到另一个数组。

int[] a = {34, 22, 44, 2, 55, 3};
int[] b = new int[a.length];

System.arraycopy(a, 0, b, 0, a.length);
assertArrayEquals(a, b);

However, we can specify the starting position for both arrays, as well as how many elements to copy.

然而,我们可以指定两个数组的起始位置,以及要复制多少个元素。

For example, let’s say we want to copy 2 elements from a, starting at a[1] to b, starting at b[3]:

例如,假设我们想从a复制2个元素,从a[1]开始到b,从b[3]开始。

System.arraycopy(a, 1, b, 3, 2); 
assertArrayEquals(new int[] {0, 0, 0, 22, 44, 0}, b);

Also, remember that arraycopy will throw:

另外,请记住,arraycopy会抛出。

  • NullPointerException if either array is null
  • IndexOutOfBoundsException if the copy references either array beyond its range
  • ArrayStoreException if the copy results in a type mismatch

3.3. Observing Date and Time

3.3.观察日期和时间

There’re two methods related to time in System. One is currentTimeMillis and the other is nanoTime.

System中,有两个与时间相关的方法。一个是currentTimeMillis,另一个是nanoTime

currentTimeMillis returns the number of milliseconds passed since the Unix Epoch, which is January 1, 1970 12:00 AM UTC:

currentTimeMillis返回自Unix Epoch(即1970年1月1日12:00 AM UTC)以来的毫秒数。

public long nowPlusOneHour() {
    return System.currentTimeMillis() + 3600 * 1000L;
}

public String nowPrettyPrinted() {
    return new Date(System.currentTimeMillis()).toString();
}

nanoTime returns the time relative to JVM startup. We can call it multiple times to mark the passage of time in the application:

nanoTime返回相对于JVM启动的时间。我们可以多次调用它来标记应用程序中的时间流逝。

long startTime = System.nanoTime();
// ...
long endTime = System.nanoTime();

assertTrue(endTime - startTime < 10000);

Note that since nanoTime is so fine-grained, it’s safer to do endTime – startTime < 10000 than endTime < startTime due to the possibility of numerical overflow.

请注意,由于nanoTime是如此精细,由于endTime – startTime < 10000endTime < startTime更安全,因为有可能出现数字溢出

3.4. Exiting the Program

3.4.退出程序

If we want to programmatically exit the currently executed program, System.exit will do the trick.

如果我们想以编程方式退出当前执行的程序,System.exit就可以做到这一点。

To invoke exit, we need to specify an exit code, which will get sent to the console or shell that launched the program.

要调用exit,我们需要指定一个退出代码,它将被发送到启动该程序的控制台或shell。

By convention in Unix, a status of 0 means a normal exit, while non-zero means some error occurred:

按照Unix的惯例,状态为0意味着正常退出,而非0意味着发生了一些错误。

if (error) {
    System.exit(1);
} else {
    System.exit(0);
}

Note that for most programs nowadays, it’d be strange to need to call this. When called in a web server application, for example, it may take down the entire site!

请注意,对于现在的大多数程序,需要调用这个是很奇怪的。例如,当在一个网络服务器应用程序中调用时,它可能会使整个网站瘫痪!

3.5. Accessing Runtime Properties

3.5.访问运行时属性

System provides access to runtime properties with getProperty.

System通过getProperty提供对运行时属性的访问。

And we can manage them with setProperty and clearProperty:

我们可以用setPropertyclearProperty管理它们。

public String getJavaVMVendor() {
    System.getProperty("java.vm.vendor");
}
    
System.setProperty("abckey", "abcvaluefoo");
assertEquals("abcvaluefoo", System.getProperty("abckey"));

System.clearProperty("abckey");
assertNull(System.getProperty("abckey"));

Properties specified via -D are accessible via getProperty.

通过-D指定的属性可以通过getProperty访问。

We can also provide a default:

我们也可以提供一个默认值。

System.clearProperty("dbHost");
String myKey = System.getProperty("dbHost", "db.host.com");
assertEquals("db.host.com", myKey);

And System.getProperties provides a collection of all system properties:

System.getProperties提供了一个所有系统属性的集合。

Properties properties = System.getProperties();

From which we can do any Properties operations:

我们可以从中进行任何属性操作。

public void clearAllProperties() {
    System.getProperties().clear();
}

3.6. Accessing Environment Variables

3.6.访问环境变量

System also provides read-only access to environment variables with getenv.

System还通过getenv提供对环境变量的只读访问。

If we want to access the PATH environment variable, for example, we can do:

例如,如果我们想访问PATH环境变量,我们可以这样做。

public String getPath() {
    return System.getenv("PATH");
}

3.7. Administering Garbage Collection

3.7.管理垃圾收集

Typically, garbage collection efforts are opaque to our programs. On occasion, though, we may want to make a direct suggestion to the JVM.

通常情况下,垃圾收集工作对我们的程序是不透明的。但有时,我们可能想直接向JVM提出建议。

System.runFinalization is a method that allows us to suggest that the JVM run its finalize routine.

System.runFinalization是一个方法,它允许我们建议JVM运行其finalize例程。

System.gc is a method that allows us to suggest that the JVM run its garbage collection routine.

System.gc是一种方法,它允许我们建议JVM运行其垃圾收集程序。

Since contracts of these two methods don’t guarantee that finalization or garbage collection will run, their usefulness is narrow.

由于这两种方法的合约并不能保证最终化或垃圾收集的运行,因此它们的用处很窄。

However, they could be exercised as an optimization, say invoking gc when a desktop app gets minimized:

然而,它们可以作为一种优化来行使,例如,当一个桌面应用程序被最小化时调用gc

public void windowStateChanged(WindowEvent event) {
    if ( event == WindowEvent.WINDOW_DEACTIVATED ) {
        System.gc(); // if it ends up running, great!
    }
}

For more on finalization, check out our finalize guide.

关于最终化的更多信息,请查看我们的最终化指南

4. Conclusion

4.结论

In this article, we got to see some of the fields and methods System provides. The complete list can be found in the official System documentation.

在这篇文章中,我们看到了System提供的一些字段和方法。完整的列表可以在官方的系统文档中找到。

Also, check out all the examples in this article over on Github.

此外,请查看本文在Github上的所有例子