我正在使用java库(jar文件)。该文件的作者放入了一堆System.out.print
和System.out.println
s。有没有办法为特定对象隐藏这些消息?
*编辑:看起来jar文件似乎在创建一堆线程,每个线程都有自己的System.out.println ...
答案 0 :(得分:41)
使用 Dummy 更改原始的 PrintStream ,并且不使用write()
方法。
完成后不要忘记替换原来的 PrintStream 。
System.out.println("NOW YOU CAN SEE ME");
PrintStream originalStream = System.out;
PrintStream dummyStream = new PrintStream(new OutputStream(){
public void write(int b) {
// NO-OP
}
});
System.setOut(dummyStream);
System.out.println("NOW YOU CAN NOT");
System.setOut(originalStream);
System.out.println("NOW YOU CAN SEE ME AGAIN");
答案 1 :(得分:6)
System.setOut();
可能就是你要找的东西
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
// NO-OP
}
}));
答案 2 :(得分:4)
除了以前发布的内容之外,我还有两种方法可以做到这一点:
1.使用Java反编译器删除每个System.out
调用并重新编译jar。如果你选择这条路线,我会推荐this one
2.您可以使用堆栈跟踪查找调用类型。 (来自How do I find the caller of a method using stacktrace or reflection?)
List<String> classNames = ...
final PrintStream originalOut = System.out;
PrintStream filterStream = new PrintStream(new OutputStream() {
public void write(int b) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if(!classNames.contains(stackTraceElements[someNumber].getClassName()){
originalOut.write(b);
}
}
});
System.setOut(filterStream);
其中classNames
是jar文件中每个类的完全限定名称,而someNumber
是堆栈中正确的位置,您需要查看(可能是1或2)。
/ E1
经过一些测试后,我认为someNumber
所需的数字是10或11.这是因为System.out.print
没有直接调用write
方法。
用于编写h
的示例堆栈跟踪:
(堆栈跟踪在索引中,getClassName
,getFileName
,getMethodName
顺序。)
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null write
9 java.io.PrintStream null print
10 java.io.PrintStream null println
11 reflection.StackTrace StackTrace.java main
用于编写\n
的示例堆栈跟踪:
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null newLine
9 java.io.PrintStream null println
10 reflection.StackTrace StackTrace.java main
reflection.StackTrace
是我用来进行测试的主要类。 reflection.StackTrace$1
是我的filterStream
,我正在System.out.println
main
方法中调用reflection.StackTrace
。{/ p>
/ E2
这11或10的差异似乎是因为println
调用print
和newLine
。 print
继续调用write
,而newLine
直接将新行字符写入流。但这并不重要,因为jar不会包含java.io.PrintStream
。
答案 3 :(得分:0)
如果你有一个更大的程序,请考虑像
public abstract class Output {
private static final PrintStream out = System.out;
private static final PrintStream dummy = new PrintStream(new OutputStream() {@Override public void write(int b){} });
private static boolean globalOutputOn = true;
public static void toggleOutput() {
System.setOut((globalOutputOn=!globalOutputOn)?dummy:out);
}
public static void toggleOutput(boolean on) {
globalOutputOn = on;
System.setOut(on?out:dummy);
}
}
这保证您可以在不同的类中打开和关闭输出,同时保证能够在以后打开输出。
例如,您可以通过调用
来使用它 toggleOutput(false)
在每个方法的开头和
toggleOutput(true)
。
答案 4 :(得分:0)
您的问题的解决方法是方法SysOutController.ignoreSysout();
中的here..