天天说用System.out.println来输出,那么我有个小问题想请教,out是一个变量还是一个内部类呢?大型而系统的知识都有各种专题来详解,这些散碎的知识点我们也不能忽视,否则面试的时候被问到这么简单的问题,答不上来,就很尴尬了。
system作为系统类,在jdk的java.lang包中,可见它也是一种java的核心语言特性。system类的构造器由private修饰,不允许被实例化。因此,类中的方法也都是static修饰的静态方法。
public final static InputStream in; //标准输入流 public final static PrintStream out; //标准输出流 public final static PrintStream err; //标准错误流
由此可见,System中的out和in都不是内部类,而是货真价实的字段变量。out是PrintStream的final static修饰的变量字段,也就是说它可以调用PrintStream类的方法。println是PrintStream的一种输出方法,所以我们通常采用System.out.println()在控制台输出内容。
public static void main(String[] args) {
int[] arr1 = { 0, 1, 2, 3, 4 };
int[] arr2 = { 9, 9, 9, 9, 9 };
System.arraycopy(arr1, 2, arr2, 0, 3);
arr1[3] = 8;
for (int i = 0; i < 5; i++)
System.out.print(arr2[i] + " ");
//2 3 4 9 9
}arraycopy方法五个参数,分别是被复制的数组,被复制的起始位置,复制到的数组,复制到这个数组的起始位置,复制到这个数组的结束位置。这个方法和Arrays中的copyOf、copyOfRange比较像,参数比较多,如果有需要也可使用。
这个就不举例了,currentTimeMillis方法和Date类中getTime方法完全是一样的,如果只是需要毫秒数,这样的调用也是很方便的。但是需要注意的是currentTimeMillis并不是直接拿到了getTime的结果,currentTimeMillis是一个本地方法,返回的是操作系统的时间,由于有的操作系统时间的最小精确度是10毫秒所以这个方法可能会导致一些偏差。
我们通过调用这个方法,在参数中输入键的字符串获取系统的属性。
立即学习“Java免费学习笔记(深入)”;
| 键 | 相关值的描述 |
|---|---|
| java.version | Java 运行时环境版本 |
| java.vendor | Java运行时环境供应商 |
| java.vendor.url | Java 供应商的 URL |
| java.home | Java 安装目录 |
| java.vm.specification.version | Java 虚拟机规范版本 |
| java.vm.specification.vendor | Java 虚拟机规范供应商 |
| java.vm.specification.name | Java 虚拟机规范名称 |
| java.vm.version | Java 虚拟机实现版本 |
| java.vm.vendor | Java 虚拟机实现供应商 |
| java.vm.name | Java 虚拟机实现名称 |
| java.specification.version | Java 运行时环境规范版本 |
| java.specification.vendor | Java 运行时环境规范供应商 |
| java.specification.name | Java 运行时环境规范名称 |
| java.class.version | Java 类格式版本号 |
| java.class.path | Java 类路径 |
| java.library.path | 加载库时搜索的路径列表 |
| java.io.tmpdir | 默认的临时文件路径 |
| java.compiler | 要使用的 JIT 编译器的名称 |
| java.ext.dirs | 一个或多个扩展目录的路径 |
| os.name | 操作系统的名称 |
| os.arch | 操作系统的架构 |
| os.version | 操作系统的版本 |
| file.separator | 文件分隔符(在 UNIX 系统中是“/”) |
| path.separator | 路径分隔符(在 UNIX 系统中是“:”) |
| line.separator | 行分隔符(在 UNIX 系统中是“/n”) |
| user.name | 用户的账户名称 |
| user.home | 用户的主目录 |
| user.dir | 用户的当前工作目录 |
在我们操作文件的时候很可能需要使用到我们的当前工作目录,可以用这个方法来获得。
public static void main(String[] args) {
String dirPath = System.getProperty("user.dir");
System.out.println(dirPath);
//输出工作目录 D:\Workspaces\MyEclipse 10\Algorithms(这是我的目录,每个人都不同)
}上面的表中就不再举例了,比较常用的是后几个key。
调用 gc 方法暗示着 Java 虚拟机做了一些努力来回收未用static0或失去了所有static1的对象,以便能够快速地重用这些对象当前占用的内存。当控制权从方法调用中返回时,虚拟机已经尽最大努力从所有丢弃的对象中回收了空间。
public static void main(String[] args) {
Date d = new Date();
d = null;
System.gc();
// 在调用这句gc方法时,上面已经失去了d引用的new Date()被回收
}实际上我们并不一定需要调用gc()方法,让编译器自己去做好了。如果调用gc方法,会在对象被回收之前调用finalize()方法,但是我们也知道finalize()方法不一定会被调用。总之java在这回收方面做的远不如c和c++。我们可以规避有关回收方面的问题。当需要了解的时候最好专门的去看JVM回收机制的文章。
exit(int)方法终止当前正在运行的 Java 虚拟机,参数解释为static2。根据惯例,非 0 的状态码表示异常终止。 而且,该方法永远不会正常返回。 这是唯一一个能够退出程序并不执行finally的情况。
Delphi 7应用编程150例 CHM全书内容下载,全书主要通过150个实例,全面、深入地介绍了用Delphi 7开发应用程序的常用方法和技巧,主要讲解了用Delphi 7进行界面效果处理、图像处理、图形与多媒体开发、系统功能控制、文件处理、网络与数据库开发,以及组件应用等内容。这些实例简单实用、典型性强、功能突出,很多实例使用的技术稍加扩展可以解决同类问题。使用本书最好的方法是通过学习掌握实例中的技术或技巧,然后使用这些技术尝试实现更复杂的功能并应用到更多方面。本书主要针对具有一定Delphi基础知识
0
public static void main(String[] args) {
try {
System.out.println("this is try");
System.exit(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("this is finally");
}
}这段程序最后只会输出 this is try 这一句话,而不会输出 this is finally 。退出虚拟机会直接杀死整个程序,已经不是从代码的层面来终止程序了,所以finally不会执行。
看完了表面的方法,我们来继续学习一下System的源代码。还是老样子,找个jdk包打开rt.jar找到java.lang.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();
}native不用看了,本机方法。这是可以猜得到的,因为System类要使用输入和输出流可能会用到和操作系统相关的一些本机方法。那么在static块中调用了registerNatives()方法,这个方法是本地方法我们看不到具体实现。但是static3说了:“VM will invoke the initializeSystemClass method to complete the initialization for this class separated from clinit”。
那么JVM调用的initializeSystemClass方法是怎么实现的呢?
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
sun.misc.VM.saveAndRemoveProperties(props);
lineSeparator = props.getProperty("line.separator");
sun.misc.Version.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
loadLibrary("zip");
Terminator.setup();
sun.misc.VM.initializeOSEnvironment();
Thread current = Thread.currentThread();
current.getThreadGroup().add(current);
setJavaLangAccess();
sun.misc.VM.booted();
}这个方法就在System类中,但是我们刚才没有介绍,因为是private的方法,只是用来自己做注册使用。我整理了一下源代码去掉了无用的部分。这个方法的大概意思是说:1.初始化Properties 2.初始化输入、输出、错误流 3.进行一大堆配置。
可以注意其中的几行,setIn0,setOut0,setErr0这三个方法。这三个方法是System中public方法setIn,setOut,setErr内部调用的子方法。我们用这几个方法来设置这三个流。
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}比如这是setIn方法,我们使用这个方法来设置输入流(此方法被使用的频率不是很高)。checkIO是检查IO流是否正确,setIn0是native方法,做真正的输入流替换工作。
private static native void setIn0(InputStream in);
以上就是 java-System系统类的深入解析的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号