Rumah > Soal Jawab > teks badan
ringa_lee2017-04-18 10:56:47
Oleh kerana System.in ialah contoh InputStream statik, anda boleh melihat dokumentasi api java
天蓬老师2017-04-18 10:56:47
Pertama sekali, System.in ialah objek jenis InputStream, yang seperti ini dalam kod sumber:
/**
* 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;
Dapat dilihat bahawa System.in tergolong dalam input standard, dan data boleh dimasukkan melalui papan kekunci atau kaedah lain.
Tetapi dalam kod sumber, objek ini tidak mempunyai kaedah permulaan (eksplisit) Dengan membaca kod sumber, anda boleh menemui kaedah berikut:
/**
* Reassigns the "standard" input stream.
*
* <p>First, if there is a security manager, its <code>checkPermission</code>
* method is called with a <code>RuntimePermission("setIO")</code> permission
* to see if it's ok to reassign the "standard" input stream.
* <p>
*
* @param in the new standard input stream.
*
* @throws SecurityException
* if a security manager exists and its
* <code>checkPermission</code> method doesn't allow
* reassigning of the standard input stream.
*
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*
* @since JDK1.1
*/
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}
private static native void setIn0(InputStream in);
Membaca komen menunjukkan bahawa kaedah ini digunakan untuk menetapkan
Mempelajari setIn0(in), dapat dilihat bahawa kaedah ini merealisasikan tetapan dalam dengan memanggil antara muka asas Jadi bagaimana ia dimulakan apabila perisian itu berlari?
Terdapat kod berikut dalam kelas Sistem:
/* 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();
}
/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
...
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));
...
}
Ia boleh dilihat daripada kod ini bahawa apabila perisian sedang berjalan, ia mula-mula menjalankan blok kod statik dan memanggil kaedah asas registerNatives() untuk memulakan kelas Sistem Kaedah ini memanggil kaedah initializeSystemClass() untuk memulakan Sistem kelas. Kedua-dua langkah ini Semua dilaksanakan melalui VM, dan kemudian membaca kaedah initializeSystemClass() Anda boleh melihat bahawa tiga keping kod dipanggil setIn0, setOut0 dan steErr0, yang memulakan tiga aliran keluaran input standard, output standard. dan ralat standard Setakat ini, System.in, out, Proses pemulaan ralat semuanya jelas.
Kaedah yang ditandakan sebagai asli ialah fungsi yang dilaksanakan oleh JVM yang memanggil kod lain Ini ada kaitan dengan lapisan bawah, saya rasa ini seperti Bootstrap Classloader sebenarnya dilaksanakan dalam C, tetapi ia dipanggil oleh JVM untuk memuatkan setiap kelas JAR asas Ia adalah serupa.
Selain itu, anda mengatakan bahawa InputStream ialah kelas abstrak (antara muka Malah, kelas antara muka dan kelas abstrak boleh digunakan sebagai parameter, tetapi pelaksanaannya pasti tidak dilaksanakan oleh mereka, tetapi boleh digunakan sebagai parameter Lagipun, kelas induk muncul di mana Kelas anak boleh diganti, jadi tiada masalah di sini