一个什么也不做的PrintStream

huangapple go评论65阅读模式
英文:

A PrintStream that does nothing

问题

我正在尝试创建一个PrintStream,每次调用其方法时都不执行任何操作。代码表面上没有错误,但当我尝试使用它时,会出现java.lang.NullPointerException: Null output stream错误。我做错了什么?

public class DoNothingPrintStream extends PrintStream {
	
	public static final DoNothingPrintStream doNothingPrintStream = new DoNothingPrintStream();

	private static final OutputStream support = new OutputStream() {
		public void write(int b) {}
	};
	// ======================================================
		// TODO | 构造函数
	
	/** 创建一个新的{@link DoNothingPrintStream}。
	 * 
	 */
	private DoNothingPrintStream() {
		super(support);
		if (support == null)
			System.out.println("DoNothingStream has null support");
	}
}
英文:

I am trying to make a PrintStream that does nothing every time its methods are invoked. The code has no error apparently, but when I try to use it I get a java.lang.NullPointerException: Null output stream. What am I doing wrong?

public class DoNothingPrintStream extends PrintStream {
	
	public static final DoNothingPrintStream doNothingPrintStream = new DoNothingPrintStream();

	private static final OutputStream support = new OutputStream() {
		public void write(int b) {}
	};
	// ======================================================
		// TODO | Constructor
	
	/** Creates a new {@link DoNothingPrintStream}.
	 * 
	 */
	private DoNothingPrintStream() {
		super( support );
		if( support == null )
			System.out.println("DoNothingStream has null support");
	}
	
	
}

答案1

得分: 5

问题出在初始化顺序上。静态字段按照你声明的顺序进行初始化(“文本顺序”),所以 doNothingPrintStreamsupport 之前被初始化。

当执行 doNothingPrintStream = new DoNothingPrintStream(); 时,support 还没有被初始化,因为它的声明在 doNothingPrintStream 的声明之后。这就是为什么在构造函数中,support 是空的。

你的“support 是空的”消息没有被打印出来,因为异常在它被打印之前被抛出了(在 super() 调用处)。

只需要交换一下声明的顺序:

private static final OutputStream support = new OutputStream() {
    public void write(int b) {}
};

public static final DoNothingPrintStream doNothingPrintStream = new DoNothingPrintStream();
英文:

The problem is in the initialisation order. Static fields are initialised in the order that you have declared them ("textual order"), so doNothingPrintStream is initialised before support.

When doNothingPrintStream = new DoNothingPrintStream(); is executing, support has not been initialised yet, because its declaration is after the declaration of doNothingPrintStream. This is why in the constructor, support is null.

Your "support is null" message doesn't get printed, because the exception got thrown (at the super() call) before it could be printed.

Just switch around the orders of the declarations:

private static final OutputStream support = new OutputStream() {
    public void write(int b) {}
};

public static final DoNothingPrintStream doNothingPrintStream = new DoNothingPrintStream();

huangapple
  • 本文由 发表于 2020年9月14日 18:31:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63882553.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定