java中System类简介(转)

上次面试中遇到的一个问题,问到System.out.println()中的out是不是内部类【不是内部类】,当时就给问蒙了,直观感觉out应该是System类的一个属性,跟内部类有什么关系?而且之前整理IO部分的时候记得有个PrintStream的类用于标准输出的,但是从没看过System的源码,也不敢随便再说了。后来看了下源码,发现的确是PrintStream,可能当时想问的是内部类的用法吧(真心感觉面试待靠缘分,很多面试官喜欢引导着问问题,方式很好,但很多时候可能让面试者搞不清你到底想问什么,我这次面试就深受打击,到最后面试官每个问题我都要先想半天是不是留了什么坑),不过归根结底自己水平差得多,还是要认真学习。 言归正传,System类是jdk提供的一个工具类,有final修饰,不可继承,由名字可以看出来,其中的操作多数和系统相关。其功能主要如下:

  • 标准输入输出,如out、in、err
  • 外部定义的属性和环境变量的访问,如getenv()/setenv()和getProperties()/setProperties()
  • 加载文件和类库的方法,如load()和loadLibrary()、
  • 一个快速拷贝数组的方法:arraycopy()
  • 一些jvm操作,如gc()、runFinalization()、exit(),该部分并未在源码的java doc中提到,可能因为本身不建议主动调用吧。而且这几个方法都仅仅是Runtime.getRuntime()的调用,两者没有区别 下边直接看图,主要的方法和功能都已经列出来。 下边我们重点来该类是如何初始化的。 首先在开头我们就可以看如下代码:
    private static native void registerNatives();
    static {
        registerNatives();
    }

    类中的静态代码块调用了一个native方法registerNatives(),可以猜到该方法应该是一个入口方法,看一下注释:通过静态初始化注册native方法,该方法会令vm通过调用initializeSystemClass方法来完成初始化工作。果然如此,那么接下来我们看下initializeSystemClass方法吧:

    private static void initializeSystemClass() {
        // 初始化props
        props = new Properties();
        initProperties(props);
        sun.misc.VM.saveAndRemoveProperties(props);
    
        //获取系统相关的换行符
        lineSeparator = props.getProperty("line.separator");
        sun.misc.Version.init();
    
        //分别创建in、out、err的实例对象,并通过setXX0()初始化,查看setXX0()方法可知,这是个native方法,将系统的标准流管理到类内的对象
        FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
        FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
        FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
        setIn0(new BufferedInputStream(fdIn));
        setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
        setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
        //加载zip包以获取java.util.zip.ZipFile这个类,以便之后加载利库使用
        loadLibrary("zip");
    
        // 设置平台相关的信号处理
        Terminator.setup();
    
        // 初始化sun.misc相关的环境变量
        sun.misc.VM.initializeOSEnvironment();
    
        // 主线程不会在同一个线程组中添加相同的线程,我们必须在这里自己实现。注释半天没弄明白,看代码就是主线程自己把自己加到了自己的线程组中......
        Thread current = Thread.currentThread();
        current.getThreadGroup().add(current);
    
        // 注册共享秘钥?注释没看明白,该方法就是实例化一个JavaLangAccess
        setJavaLangAccess();
    
        // 子系统在初始化的时候可以调用sun.misc.VM.isBooted(),以保证在application类加载器启动前不做任何事。booted()其实就是改了个状态,使isBooted()变为true。
        sun.misc.VM.booted();
    }

    至此,System基本上便讲完了,不过还有很多底层的东西没看懂(setJavaLangAccess()),留待以后解决吧。

http://www.cnblogs.com/good-temper/p/5042058.html

时间: 2024-10-01 19:38:15

java中System类简介(转)的相关文章

Java中Properties类

Java中Properties类简介 知识学而不用,就等于没用,到真正用到的时候还得重新再学. Properties类继承自Hashtable,如下: 它主要用于读取Java的配置文件,由于配置文件中的很多变量时经常改变的,通过这个类可以让用户脱离程序本身去修改相关的变量配置.在Java中,其配置文件常为.properties文件,格式为文本文件,内容的格式为“键=值”的格式,#打头的是注释行,Properties会忽略注释.允许只有key没有value,没有value时,value会被set成

hadoop中Text类 与 java中String类的区别

hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念: 字符集: 是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.例如 unicode就是一个字符集,它的目标是涵盖世界上所有国家的文字和符号: 字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对.即在符号集

Java中String类学习总结

java中String类的使用频率非常高,本人在学习此模块时,认为下列几点知识值得注意: 一.String是不可变对象 java.lang.String类使用了final修饰,不能被继承.Java程序中的所有字面值,即双引号括起的字符串,如"abc",都是作为String类的实例实现的.String是常量,其对象一旦构造就不能再被改变.换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容.而最

【转载】Java中String类的方法及说明

转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一.构造函数     String(byte[ ] bytes):通过byte数组构造字符串对象.     String(char[ ] value):通过char数组构造字符串对象.     String(Sting original):构造一个original的副本.即:拷贝一个original.     String(Strin

Java中Arrays类的两个方法:deepEquals和equals

deepEquals和equals是Java中Arrays类的两个静态方法,可是它们之间有什么样的区别呢? 代码一. import java.util.Arrays; public class Test { public static void main(String[] args) { String[][] name1 = {{ "G","a","o" },{ "H","u","a",

java中String类小结

构建一个字符串 1.用字符串直接量: String message = new String("Welcome to java"); 2.用字符串直接量: String message = "Welcome to java"; 3.用字符数组 Char[] charArray = {'m', 'y'}; String message = new String(charArray); 不可变字符与限定字符串 String对象是不可变的,内容不能改变 java虚拟机为了

Java中的类装载和初始化模块

在Java中,初始化模块是指用一对"{}"括起来的代码,可以与构造方法一起来对对象进行初始化.初始化模块又分为实例初始化模块和静态初始化模块(只能由类的静态成员引用,在类装载时进行调用) Java中,代码的执行顺序是: 1.装入类     1.1递归装入父类,直到继承链上的父类全部装入为止.     1.2类装入内存之后,静态数据域和静态初始块按照在类中出现的顺序进行执行. 2.调用类的构造方法     2.1递归调用父类的构造方法,直到父类为java.lang.Object为止.  

Java中String类与Integer类的几个方法

计算诸如-123,456,789 + 123,123的值 import java.math.BigInteger; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner cin = new Scanner(System.in); String str1, str2; BigInteger a, b; while(cin.hasNext()){ str1 = cin.

关于java中ReentrantLock类的源码分析以及总结与例子

一,官方描述 关于ReentrantLock的官方描述,英文的就不贴出来了,这里我只贴出我自己翻译的描述: reentrant是一个跟synchronized具有相同行为和语义的持有锁来访问方法和语句的互斥锁,但是reentrant还拥有被扩展的能力. ReentrantLock会被线程拥有并且持续锁定,不会解锁.线程调用lock()方法返回后,则成功持有锁,否则这个锁正在被另一个线程所持有,只能等待另一个线程释放锁,如果当前线程拥有了锁,则调用lock()方法会立即返回,这个状态可以通过isH