首先感到遗憾的是,这是一个非常基本的问题,我宣传我仍然是一个代码猴。 我在接受采访时被要求阐明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类型的对象?
答案 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()方法。