关于System.in串联流BufferedReader关闭

while(true) {
    BufferedReader br = null;
    try {
        System.out.println("输入名字:(不能重复,q结束)");
	br = new BufferedReader(new InputStreamReader(System.in));
        String name = br.readLine();
        if(name.equalsIgnoreCase("q")) {
            break;
        }
        System.out.println("输入电话号码:");
        String tel = br.readLine();
        hs.put(name, tel);
    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        try {
//         System.in.close();
            br.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

 br.close()之后再readLine就会报空指针,源头貌似BufferedInputStream中的buf属性为空

 

    /**
     * The internal buffer array where the data is stored. When necessary,
     * it may be replaced by another array of
     * a different size.
     */
    protected volatile byte buf[];

 

br.close()之后buf属性即使再初始化后仍为空,原因与System.in为static final且其实例为BufferedInputStream

但在BufferedInputStream类中调试不到buf的初始化过程,究其原因可能是

 

/**
     * Initialize the system class.  Called after thread initialization.
     */
    private static void initializeSystemClass() {
	props = new Properties();
	initProperties(props);
	sun.misc.Version.init();

        // Workaround until DownloadManager initialization is revisited.
        // Make JavaLangAccess available early enough for internal
        // Shutdown hooks to be registered
        setJavaLangAccess();

        // Gets and removes system properties that configure the Integer
        // cache used to support the object identity semantics of autoboxing.
        // At this time, the size of the cache may be controlled by the
        // vm option -XX:AutoBoxCacheMax=<size>.
        Integer.getAndRemoveCacheProperties();

	// Load the zip library now in order to keep java.util.zip.ZipFile
	// from trying to use itself to load this library later.
	loadLibrary("zip");

	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));

	// Setup Java signal handlers for HUP, TERM, and INT (where available).
        Terminator.setup();

        // Initialize any miscellenous operating system settings that need to be
        // set for the class libraries. Currently this is no-op everywhere except
        // for Windows where the process-wide error mode is set before the java.io
        // classes are used.
        sun.misc.VM.initializeOSEnvironment();

	// Set the maximum amount of direct memory.  This value is controlled
	// by the vm option -XX:MaxDirectMemorySize=<size>.  This method acts
	// as an initializer only if it is called before sun.misc.VM.booted().
 	sun.misc.VM.maxDirectMemory();

	// Set a boolean to determine whether ClassLoader.loadClass accepts
	// array syntax.  This value is controlled by the system property
	// "sun.lang.ClassLoader.allowArraySyntax".  This method acts as
	// an initializer only if it is called before sun.misc.VM.booted().
	sun.misc.VM.allowArraySyntax();

	// Subsystems that are invoked during initialization can invoke
	// sun.misc.VM.isBooted() in order to avoid doing things that should
	// wait until the application class loader has been set up.
	sun.misc.VM.booted();

        // The main thread is not added to its thread group in the same
        // way as other threads; we must do it ourselves here.
        Thread current = Thread.currentThread();
        current.getThreadGroup().add(current);
    }

 

setIn0(new BufferedInputStream(fdIn));

但initializeSystemClass方法无法调试到

 

关于虚拟机启动有官方解释:

The Java virtual machine starts up by creating an initial class, which is specified in an implementation-dependent manner, using the bootstrap class loader (§5.3.1) . The Java virtual machine then links the initial class, initializes it, and invokes its public class method void main(String[]) . The invocation of this method drives all further execution. Execution of the Java virtual machine instructions constituting the main method may cause linking (and consequently creation) of additional classes and interfaces, as well as invocation of additional methods.

http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html

既然java.lang.System类是由bootstrap class loader装载,所以其debug不能

 

 

 

2012.07.30 addition:

 

at System.java:

 

/**
     * 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 = nullInputStream();
 

通過此例來驗證:

http://stackoverflow.com/questions/8203981/closing-bufferedreader-and-system-in

Reader rdr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(rdr);
String s;
s = br.readLine();
br.close();
Scanner sc = new Scanner(System.in);
s = sc.nextLine();
System.out.print(s);

第二次使用System.in時,它的實現類是BufferedInputStream,它的成員buf和in均為null,

換言之,也就是這時System.in已經處於關閉狀態,無法使用了。

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值