初学Java时就接触过System类,该篇文章就是记录下System类下的三个属性静态常量in、out和err。
一、System类
1、源码(部分)
/**
* The <code>System</code> class contains several useful class fields
* and methods. It cannot be instantiated.
*
* <p>Among the facilities provided by the <code>System</code> class
* are standard input, standard output, and error output streams;
* access to externally defined properties and environment
* variables; a means of loading files and libraries; and a utility
* method for quickly copying a portion of an array.
*
* @author unascribed
* @since JDK1.0
*/
public final class System {
/* register the natives via the static initializer.
*
* VM will invoke the initializeSystemClass method to complete
* the initialization for this class separated from clinit.
* Note that to use properties set by the VM, see the constraints
* described in the initializeSystemClass method.
*/
private static native void registerNatives();
static {
registerNatives();
}
/** Don't let anyone instantiate this class */
private System() {
}
/**
* The "standard" input stream. This stream is already
* open and ready to supply input data. Typically this stream
* corresponds to keyboard input or another input source specified by
* the host environment or user.
*/
public final static InputStream in = null;
/**
* The "standard" output stream. This stream is already
* open and ready to accept output data. Typically this stream
* corresponds to display output or another output destination
* specified by the host environment or user.
* <p>
* For simple stand-alone Java applications, a typical way to write
* a line of output data is:
* <blockquote><pre>
* System.out.println(data)
* </pre></blockquote>
* <p>
* See the <code>println</code> methods in class <code>PrintStream</code>.
*
* @see java.io.PrintStream#println()
* @see java.io.PrintStream#println(boolean)
* @see java.io.PrintStream#println(char)
* @see java.io.PrintStream#println(char[])
* @see java.io.PrintStream#println(double)
* @see java.io.PrintStream#println(float)
* @see java.io.PrintStream#println(int)
* @see java.io.PrintStream#println(long)
* @see java.io.PrintStream#println(java.lang.Object)
* @see java.io.PrintStream#println(java.lang.String)
*/
public final static PrintStream out = null;
/**
* The "standard" error output stream. This stream is already
* open and ready to accept output data.
* <p>
* Typically this stream corresponds to display output or another
* output destination specified by the host environment or user. By
* convention, this output stream is used to display error messages
* or other information that should come to the immediate attention
* of a user even if the principal output stream, the value of the
* variable <code>out</code>, has been redirected to a file or other
* destination that is typically not continuously monitored.
*/
public final static PrintStream err = null;
...
}
2、从上可以看出:
System类由final修饰,所以不能被继承;
System类的构造方法是由private修饰,不能被实例化;
System类这种final类是在JVM启动时就会被初始化,类里面的静态变量等都是能直接调用的;
in、out、err等都是静态常量,通过类名可直接引用。
3、System类中的属性、方法简介
(1)标准输入输出, 如out、in、err
(2)外部定义的属性和环境变量的访问,如getenv()/setenv()和
(3)getProperties()/setProperties()
(4)加载文件和类库的方法,如load()和loadLibrary()、
(5)快速拷贝数组的方法:arraycopy()
(6)jvm操作:如gc()、runFinalization()、exit(),该部分并未在源码的java doc中提到,可能因为本身不建议主动调用吧。而且这几个方法都仅仅是Runtime.getRuntime()的调用,两者没有区别
(7)获取时间方法:System.nanoTime 和 System.currentTimeMillis
二、in、out和err
1、System.in
System.in是一个典型的连接控制台程序和键盘输入的InputStream流。通常当数据通过命令行参数或者配置文件传递给命令行Java程序的时候,System.in并不是很常用。图形界面程序通过界面传递参数给程序,这是一块单独的Java IO输入机制。
2、System.out
System.out是一个PrintStream流。System.out一般会把你写到其中的数据输出到控制台上。System.out通常仅用在类似命令行工具的控制台程序上。System.out也经常用于打印程序的调试信息(尽管它可能并不是获取程序调试信息的最佳方式)。
3、System.err
System.err是一个PrintStream流。System.err与System.out的运行方式类似,但它更多的是用于打印错误文本。一些类似Eclipse的程序,为了让错误信息更加显眼,会将错误信息以红色文本的形式通过System.err输出到控制台上。
4、实例
public static void main(String[] args) throws IOException {
InputStream in = System.in;// 输入流
PrintStream out = System.out;// 输出流
PrintStream err = System.err;//输出流(一般用于错误写)
try {
byte[] buffer = new byte[10];
int len = 0;// 读取之后的实际长度
// 在UTF8编码下,回车\r 换行\n 也各占1个字节
/*
* read方法参数:
* b:读入数据的缓冲区。
* off:数组 b 中将写入数据的初始偏移量。
* len:要读取的最大字节数。
*/
while ((len = in.read(buffer, 0, 4)) != -1) { //读取操作
System.out.println("读取的实际长度--------------------------" + len);
out.write(buffer, 0, 4); //写出的操作
System.out.println("--------------------------");
}
} catch (IOException e) {
err.println(e.getMessage());
e.printStackTrace();
} finally {
try{
in.close();
out.close();
err.close();
} catch (Exception e){
System.err.println(e.getMessage());
}
}
}
//输入:
0123456789abc
//结果如下:
读取的实际长度--------------------------4
0123--------------------------
读取的实际长度--------------------------4
4567--------------------------
读取的实际长度--------------------------4
89ab--------------------------
读取的实际长度--------------------------2
c
ab--------------------------
以梦为马,以汗为泉,不忘初心,不负韶华。