关于System.in.read()

dracularking 2013-04-06 11:28:01
import java.io.IOException;

public class Test {

public static void main(String[] args) {

int s = 0;
try {
s = System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(s);

}

}


就这样一个程序,比如输入1,打印出49
说明是按char的方式对待输入

但是看System.in

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

/**
* The following two methods exist because in, out, and err must be
* initialized to null. The compiler, however, cannot be permitted to
* inline access to them, since they are later set to more sensible values
* by initializeSystemClass().
*/
private static InputStream nullInputStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
return null;
}
throw new NullPointerException();
}


一个被赋值为null的final型变量是如何调用read方法的?还有和char是如何关联起来的



...全文
168 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2013-04-09
  • 打赏
  • 举报
回复
引用 7 楼 kiritor 的回复:
引用 6 楼 ZangXT 的回复:http://bbs.csdn.net/topics/270089548 这里已经看到了,但是真正哪里初始化的还是有点模糊呢
private static void initializeSystemClass() 这个类是私有的,那么只有反射调用或者native方式执行了。 它也说过Called after thread initialization.但是对虚拟机启动时thread initialization的概念还不清楚
dracularking 2013-04-07
  • 打赏
  • 举报
回复
不过即使是在BufferedInputStream中也还没发现和char有关的蛛丝马迹
dracularking 2013-04-07
  • 打赏
  • 举报
回复
引用 6 楼 ZangXT 的回复:
http://bbs.csdn.net/topics/270089548
这个东东真的很有意思

/*
 * The following three functions implement setter methods for
 * java.lang.System.{in, out, err}. They are natively implemented
 * because they violate the semantics of the language (i.e. set final
 * variable).
 */
JNIEXPORT void JNICALL
Java_java_lang_System_setIn0(JNIEnv *env, jclass cla, jobject stream)
{
    jfieldID fid =
        (*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");
    if (fid == 0)
        return;
    (*env)->SetStaticObjectField(env,cla,fid,stream);
}
native的操作违反了java语法,对final型变量进行了再注入,这是如何绕开语法层面的限制的,意思就是绕开编译器,直接对字节码进行修改或者直接在jvm中修改了?类似于byte instrumentation?
LCore 2013-04-06
  • 打赏
  • 举报
回复
引用 楼主 dracularking 的回复:
Java code?1234567891011121314151617import java.io.IOException; public class Test { public static void main(String[] args) { int s = 0; try { s = System.in.re……
read()方法应该是按照byte的方式来对待输入输出的。 至于第二个问题通过查阅api,应该是在System类中进行初始化 之后调用read()方法的。看看它所描述的信息吧
public final class 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();
    }
......
}
通过这个静态代码块,和上面的注释信息jvm会调用 一个叫做initializeSystemClass的方法
 private static void initializeSystemClass() {

        // VM might invoke JNU_NewStringPlatform() to set those encoding
        // sensitive properties (user.home, user.name, boot.class.path, etc.)
        // during "props" initialization, in which it may need access, via
        // System.getProperty(), to the related system encoding property that
        // have been initialized (put into "props") at early stage of the
        // initialization. So make sure the "props" is available at the
        // very beginning of the initialization and all system properties to
        // be put into it directly.
        props = new Properties();
        initProperties(props);  // initialized by the VM

        // There are certain system configurations that may be controlled by
        // VM options such as the maximum amount of direct memory and
        // Integer cache size used to support the object identity semantics
        // of autoboxing.  Typically, the library will obtain these values
        // from the properties set by the VM.  If the properties are for
        // internal implementation use only, these properties should be
        // removed from the system properties.
        //
        // See java.lang.Integer.IntegerCache and the
        // sun.misc.VM.saveAndRemoveProperties method for example.
        //
        // Save a private copy of the system properties object that
        // can only be accessed by the internal implementation.  Remove
        // certain system properties that are not intended for public access.
        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(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
        setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
        // 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");

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

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

        // register shared secrets
        setJavaLangAccess();

        // 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.
        // IMPORTANT: Ensure that this remains the last initialization action!
        sun.misc.VM.booted();
    }
a1216164960 2013-04-06
  • 打赏
  • 举报
回复
来学习的~~~~
LCore 2013-04-06
  • 打赏
  • 举报
回复
引用 6 楼 ZangXT 的回复:
http://bbs.csdn.net/topics/270089548
这里已经看到了,但是真正哪里初始化的还是有点模糊呢
ZangXT 2013-04-06
  • 打赏
  • 举报
回复
LCore 2013-04-06
  • 打赏
  • 举报
回复
确实,等待了解这个过程的开解惑
dracularking 2013-04-06
  • 打赏
  • 举报
回复
引用 2 楼 kiritor 的回复:
引用 楼主 dracularking 的回复:Java code?1234567891011121314151617import java.io.IOException; public class Test { public static void main(String[] args) { int s = 0; try { ……
谢谢认真回复 我看了这个方法 /** * Initialize the system class. Called after thread initialization. */ private static void initializeSystemClass() 名字是initializeSystemClass,貌似有戏,但是好像没有明显有关in这个属性的初始化 况且in本身是final且有initializer的 再看方法说明,是在线程初始化后被调用的,时间节点上和final类初始化可能有出入
LCore 2013-04-06
  • 打赏
  • 举报
回复
不过其内部到底是如何"工作"的 小生现在一头雾水,求大牛解决! 不要沉了啊!

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧