`

关于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已經處於關閉狀態,無法使用了。

 

 

 

 

 

分享到:
评论
2 楼 dracularking 2012-07-30  
didixp 写道
br.close()连System.in的流都一同关了.必然无法再读取了.

对,这是装饰者模式的一种连锁关闭机制,但是一种什么样的机制让System.in被关闭后无法再开启呢?
1 楼 didixp 2012-05-31  
br.close()连System.in的流都一同关了.必然无法再读取了.

相关推荐

    Java I/O 标准输入输出流System.in

    在Java编程语言中,I/O(输入/输出)是程序与外部世界交互的重要部分,而标准输入输出流(System.in, System.out, System.err)是Java内置的预定义流,用于处理程序与操作系统之间的基本输入输出操作。这篇博客将深入...

    import java.io.*; public class FirstPart{ public static void main(String[] args) throws Exception{ System.out.print("The input Fahrenheit is "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int f = Integer.parseInt(br.re

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int f = Integer.parseInt(br.readLine()); double c=5*(f-32); c=c/9; System.out.println("Changing it to Celsius is "+c); } }

    import java.io.BufferedReader.docx

    - 首先创建了一个 `BufferedReader` 对象,其内部使用了 `InputStreamReader` 来处理标准输入流 `System.in`。 - 使用 `System.out.print` 打印提示信息,请求用户输入数字。 - 通过调用 `readLine()` 方法读取用户...

    java代码-System.in.read()测试

    在Java编程语言中,`System.in.read()`是一个用于从标准输入流(stdin)读取单个字节数据的方法。这个方法广泛应用于命令行程序,允许用户通过键盘输入数据与程序进行交互。在这个“java代码-System.in.read()测试”...

    Java文件io-stream-file教程

    为了获得一个绑定到控制台的字符流,可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。BufferedReader 对象创建后,可以使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个...

    SystemIn:用于从 Java 控制台读取的 Java API (System.in)

    Java API中的`System....通过查看源码,我们可以学习到更多关于如何高效、灵活地使用`System.in`进行控制台输入处理的知识。如果你需要深入理解或改进控制台输入的处理,这个项目可能提供了一些实用的方法和最佳实践。

    Java 详解BufferedReader

    - 这行代码创建了一个 `BufferedReader` 对象,并将其绑定到标准输入流 `System.in` 上。`InputStreamReader` 负责将字节流转换为字符流。 2. **读取输入**: - `System.out.print("请输入一行文字:");` - 在...

    java输入输出语句.doc

    Java 系统预先定义了三个流对象:System.out、System.in 和 System.err。其中,System.out 是标准输出流,用于将数据输出到屏幕上;System.in 是标准输入流,用于从键盘输入数据;System.err 是标准错误设备,用于...

    在Java中从命令控制台输入数据的一些常用方法.doc

    这可以通过多种方式实现,包括使用`System.in`、`Scanner`类、`BufferedReader`类等。下面将详细介绍这些方法及其应用场景。 #### 1. 使用标准输入流对象 `System.in` 在Java中,`System.in`是一个标准输入流对象...

    java输入输出语句整理总结.doc

    Java 输入输出语句整理总结 Java 输入输出语句是 Java 编程语言中最基本也是最重要的部分之一。...同时,Java 也提供了多种输入输出语句,例如 `System.out.print()`、`System.in.read()` 和 `BufferedReader` 等。

    引用 Java中从命令控制台输入数据的几种常用方法.doc

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String tx = br.readLine(); System.out.println(tx); } } ``` 方法四:使用 JOptionPane JOptionPane 是 Java 中的一个 GUI ...

    Java中从命令控制台输入数据的几种常用方法

    本文将详细介绍几种常用的在Java中从命令控制台输入数据的方法,包括直接使用`System.in`、使用`java.util.Scanner`类、使用`java.io.BufferedReader`类以及利用图形用户界面(GUI)组件进行输入。 ### 1. 使用`...

    Java编程模拟练习题(含答案).

    InputStreamReader reader = new InputStreamReader(System.in); BufferedReader input = new BufferedReader(reader); String s = input.readLine(); // 读取第一行输入 double v1 = Double.parseDouble(s); ...

    603.601.JAVA基础教程_IO流-标准的输入、输出流(603).rar

    我们通常使用`BufferedReader`或`Scanner`类来包装`System.in`,以便更方便地处理用户输入。例如: ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner ...

    Java中的标准IO方法

    Java提供了一系列的类和方法来处理输入输出流,主要包括`System.in`,`Scanner`以及`BufferedReader`。 一、System.in 在Java中,`System.in`是一个预定义的`InputStream`对象,用于读取标准输入,通常是键盘输入。...

    Java控制台数据获取方法及比较.pdf

    System.in是一个InputStream对象,表示标准输入流。可以使用BufferedReader类来读取数据。示例代码如下: ```java import java.io.IOException; import java.io.InputStreamReader; public class Example1 { ...

Global site tag (gtag.js) - Google Analytics