我看不懂这句话public final static PrintStream out = nullPrintStream();,能帮忙解释一下吗?
解决方案 »
- 建立一个gui程序,实现下列至少5个组件,大家有什么好的想法吗?
- 晕了,问题越弄越多了?java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
- 如何从JPanel输出图像到PDF?
- 十分困惑,请教java中函数的传参方式。
- 150分:求一个例子,当你碰到一个技术难题时,你一般怎么样去解决它?
- 图形用户界面显示的一简单问题!
- 请高手指教,学习JDK原码时发现的问题
- 最简单的一APPLET,不用JRE的plug-in,为何不能运行,该如何处理?郁闷之极。。。
- 又一个关于运行期类型鉴定的问题
- 为什么会是:) Runtime Exception ,有些看不懂:(
- 急,急,急!!!请高手指点
- 关于窗体最大最小化按钮
System.out.println里的out到底是普通字段还是对象?
如果是普通字段(属性),那么System.out.println这样的写法是不成立的吧?我看了System类的源码,我发现是把out定义为普通对象的
而在System类的源码里,并没有println这个方法啊
晕
调用System里面的out
再调用out里面的println
out是PrintStream类型,所以要到PrintStream类里找println
看定义,似乎是普通对象吧public final static PrintStream out = nullPrintStream();
如下定义似乎是一个对象类型
可是这个out为什么不是PrintStream out = new PrintStream()呢?
而是,我看了不解
public final static PrintStream out = nullPrintStream();
System类的开头有一段:
static {
registerNatives();
}
这段代码会在虚拟机启动的时候就执行,它在虚拟机里注册System需要使用的一些本地代码
比如:
private static native Properties initProperties(Properties props);
private static native void setOut0(PrintStream out);
在windows下的话,它就告诉虚拟机到哪个dll文件里去找相应的实现
/**
* 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();
}
也就说in, out, and err 初始化为null,然后会在后来由initializeSystemClass()方法类初始化成有意义的值/**
* Initialize the system class. Called after thread initialization.
*/
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
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)); !!! // Enough of the world is now in place that we can risk
// initializing the logging configuration.
try {
java.util.logging.LogManager.getLogManager().readConfiguration();
} catch (Exception ex) {
// System.err.println("Can´t read logging configuration:");
// ex.printStackTrace();
} // 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"); // 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();
}
in,out,err就是在以上方法以下三条语句里初始化的.setIn0(new BufferedInputStream(fdIn)); !!!
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); !!!
setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); !!!
看
private static native void setIn0(InputStream in);
这是个native函数,是前面registerNatives()的时候注册了的.这个函数应该是把实际连接到输入输出设备的句柄传给虚拟机并赋值给in,out,err 这么解释明白了吗?
不明白,更糊涂了
不明白什么是native函数
不明白建立对象为什么不用new
private static InputStream nullInputStream() throws NullPointerException
方法的说明里已经告诉我们为什么这么写了,简单的说它要先被初始化成null,然后再由initializeSystemClass()
方法初始化。
好好研究一下下面这段英文
/**
* 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().
*/
累啊,楼主,牺牲了我午休的时间...
既然out是一个对象,为什么不用new?影响你午休了,sorry
赋给out
你就理解成String str = disposal();其中disposal是你随便定义的一个函数,只不过该函数返回一个String的值而已....
你再不理解就去看书吧....
这样说似乎能理解了,可是为什么不直接new呢?
建立对象似乎除了new还有别的方法?
不然不是浪费系统开销嘛。
建立对象可以直接A a = new A();
也可以丛一个函数中得到返回值,但归根结底你可以简单理解为都是new出来的啥时候结贴给分啊?
out肯定是对象,这点不用怀疑。
给你举个简单的例子,明白了你就明白你的问题了public class A {
public final static PrintStream out = nullPrintStream(); //nullPrintStream是个方法,返回值是PrintStream对象 public static PrintStream nullPrintStream() {
//return new PrintStream();
return null; //new一个对象返回还是返回空对象,由写程序的人决定
} public static void setOut(PrintStream o) {
out = o; //给out赋值
} public static void main(String[] args) {
setOut(new PrintStream());
out.println("hello");
}
}
public class A {
//把final去掉,否则常量就不能再改变了
public static PrintStream out = nullPrintStream(); //nullPrintStream是个方法,返回值是PrintStream对象 public static PrintStream nullPrintStream() {
//return new PrintStream();
return null; //new一个对象返回还是返回空对象,由写程序的人决定
} public static void setOut(PrintStream o) {
out = o; //给out赋值
} public static void main(String[] args) {
setOut(new PrintStream());
out.println("hello");
}
}在java的层次上,建立一个对象,除了new和反射的newInstance以外,应该没有别的方法了
这里用setOut可以给out赋值,但这个赋值这个对象也是new出来的,native方法内部,应该也是new一块内存出来的
都怪我理解能力太差,
要么显式地new
要么用方法赋值,方法的返回值是一个对象,相当于隐式地new了