在System.out.println()中输出

时间:2012-02-26 16:34:43

标签: java jvm system

首先感到遗憾的是,这是一个非常基本的问题,我宣传我仍然是一个代码猴。 我在接受采访时被要求阐明System.out.println(); 我解释了以下方式

//this class belongs to java.lang package
class System{
  public static PrintStream out;
}
//this class belongs to java.io package
class PrintStream{
 public void println..
}

我已经解释过System.out是有效的,因为这是我们在java中访问静态变量的方式,而out是PrintStream的一个对象,因此我们可以访问它的方法,总之为

System.out.pritnln(); 

他让我模拟一个类似的程序,我跟踪并且它没有用,因为System.out返回null

我的问题是在java中实例化对象的位置是什么?如果我没错,它是一个预定义的对象吗?什么应该是对此的细致解释。

技术上我们应该叫什么?是PrintStream类型的变量还是应该将其称为PrintStream类型的对象?

8 个答案:

答案 0 :(得分:21)

当实例化类时,System.out被初始化为null。这是由nullPrintStream()中的System.java方法设置的,只返回null

当JVM初始化时,它会调用initializeSystemClass()方法。此方法调用native方法setOut0(),将out变量设置为适当的值。

这可能看起来很奇怪,但由于以下原因,这是必要的操作:

  • out无法静态设置为该值,因为System必须是首批加载的类之一(PrintStream之前)。
  • out必须为final,以便用户无法直接覆盖其值。
  • 由于out无法静态设置,并且是最终版,因此我们必须使用native方法setOut0()覆盖语言的语义。

我希望这有助于你理解。

答案 1 :(得分:6)

System.out是一个普通的静态属性,它是由JVM在JVM初始化期间通过initializeSystemClass()方法设置的。您甚至可以通过调用System.setOut(printOutStream);更改它(尽管不建议这样做),其中printOutStream是您要用作标准输出的流。

这是一个很好的article详细说明System.out.println()如何工作。

答案 2 :(得分:0)

System.out由JVM提供。在调用main方法时,System.out已打开并可以使用。

请参阅http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#out

答案 3 :(得分:0)

在Oracle Java运行时库中,它使用registerNatives()本机方法进行本机实例化,该方法在加载static类时被调用(通过System初始值设定项)。然而,这是一个实现细节。

您也可以使用System.out直接设置System.setOut()

答案 4 :(得分:0)

Out in System.out.println是System类中PrintWriter的静态字段(对象),println是PrintWriter的方法。

参考: 系统:http://docs.oracle.com/javase/6/docs/api/java/lang/System.html PrintWriter:http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html

答案 5 :(得分:0)

甚至没有必要去网络和文档。我们可以简单地说javap java.lang.System,它给出了所有静态字段的列表,属于System类的方法原型。 我们可以使用javap获取任何java类的详细信息,前提是您知道它的包和类名 out是在System类中定义的PrintStream的公共静态对象。

答案 6 :(得分:0)

当System类初始化时,它会调用initializeSystemClass()方法,这里是代码:

FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));

在此代码中,setOut0()是在System.c中实现的本机函数:

JNIEXPORT void JNICALL
Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream)
{
    jfieldID fid =
        (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
    if (fid == 0)
        return;
    (*env)->SetStaticObjectField(env,cla,fid,stream);
}

这是一个标准的JNI代码,它将System.out设置为传递给它的参数,此方法调用本机方法setOut0(),它将out变量设置为适当的值。

System.out是最终的,这意味着它不能在initializeSystemClass()中设置为其他内容,但使用本机代码可以修改最终变量。

答案 7 :(得分:-7)

的System.out.println();

这里println是printstream类的对象。我们不能直接为printstream类创建对象。 Out是系统类的对象。 out在系统类中称为字段。在调用system.out时,它间接为printstream类创建对象。因此我们可以使用System.out.prontln()调用println()方法。