没有System.out怎么办,在控制台上打印?

我最近在接受采访时遇到了一个问题。 问题表示为 – >假设您无法访问Jdk API中的System类,也无法使用ECHO,您在JRE 5环境中,如何在控制台上打印任何内容? 问题真正开始于 – 为什么Java给了我们PrintStream对象System.out ??为什么它是最终的? 没有任何其他方法可以在控制台上打印任何东西。

如果需要,可以绕过System对象。 System.out做了很多额外的事情(例如处理unicode),所以如果你真的只想要原始输出和性能,你实际上甚至可能绕过它。

import java.io.*; public class PrintOutTest { public static void main(String args[]) throws IOException { BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileDescriptor.out), "ASCII"), 512); out.write("test string"); out.write('\n'); out.flush(); } } 

这里已经进一步阐述了这一点。

PrintStream是最终的,因为它可以完成Windows控制台/可以执行的所有操作。 同样,“Console”是C#中的const类。 这些类封装了控制台可以执行的所有操作,并且它仅以一种特定方式执行。 你不能“让它变得更好”,因为在某种程度上,处理它是由操作系统决定的。

有很多方法可以在屏幕上输出内容:

  1. 以@eis的方式编写自己的OutputStream
  2. 使用JNI并在本机DLL / SO中调用一个方法来调用printf()类的本机函数
  3. 使用Runtime.getRuntime().exec()并调用echo程序,列表如下。

+1到@eis

您可以使用JDK的记录器 (java.util.logging.Logger)。

这是您在java类中创建记录器的方法。

 import java.util.logging.Logger; private final static Logger LOGGER = Logger.getLogger(MyClass.class .getName()); 

您也可以将log4j用于相同的目的。

如上所述的面试问题是非常不正常的(即人为的),解决它涉及走出纯Java之外。 这肯定不是你在正常情况下会考虑做的事情。

其他答案给了你一些半解决方案……如果你真的,真的必须这样做。 (我说半解决方案,因为他们大多不处理应用程序的stdout / stderr流被重定向到控制台以外的其他地方的情况。这是这个问题的唯一“真实”方面……)

如果你可以使用System类(在JDK 6上)…打印到控制台的干净方式(例如,如果System.out已被重定向)是使用System.console()方法获取Console对象,并使用那是为了得到一个Writer

但请注意,如果JVM没有关联的控制台,则console()将返回null


问题真正开始于 – 为什么Java给了我们PrintStream对象System.out? 为什么它是最终的? 没有任何其他方法可以在控制台上打印任何东西。

答案是:

  1. 为了方便。
  2. 所以随机代码不会意外地破坏它。 (或者故意如果您需要担心在JVM中运行不受信任的代码。)但是,可信代码实际上可以通过调用System.setOut(...) 更改System.out 。 这样可以在幕后魔术中安全地改变final变量的状态。 (我相信JIT编译器知道这一点,并以不同的方式处理这3个final变量。)
  3. 是。 见上文,和(哎呀!)其他答案。

正如文件所述,

System类包含几个有用的类字段和方法。 它无法实例化。

因此,正如您所看到的,System类是一种用于不同有用function的容器。 所有这些字段和方法都是静态的,因此没有任何理由扩展它。
Java为我们提供了static PrintStream out因为它是与程序通信的默认方式 – 使用控制台。
如果你不同意我的意思,请告诉我。

我今天找到了解决问题的方法。 我正在使用org.apache.log4j来获得这个答案。 这里有很多其他的方式。 谢谢。

 import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; public class HelloByLogger { private final static Logger logger = Logger.getLogger(HelloByLogger.class); public static void main(String[] args) { BasicConfigurator.configure(); logger.info("From Logger... Ola!"); } }