我正在使用java庫(jar文件)。該文件的作者放在一堆System.out.print
和System.out.println
s。有什麼方法可以隱藏特定對象的這些消息嗎?隱藏System.out.print類的調用
*編輯:它看起來像jar文件似乎建立了一堆的線程和每個線程都有它自己的System.out.println的...
我正在使用java庫(jar文件)。該文件的作者放在一堆System.out.print
和System.out.println
s。有什麼方法可以隱藏特定對象的這些消息嗎?隱藏System.out.print類的調用
*編輯:它看起來像jar文件似乎建立了一堆的線程和每個線程都有它自己的System.out.println的...
System.setOut();
可能是你在找什麼
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
// NO-OP
}
}));
更改原始的PrintStream與虛擬上根本上是什麼方法。
當你完成時,不要忘記取代原來的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.使用Java反編譯器,並刪除每個System.out
調用並重新編譯罐子。如果您選擇此路線,我會推薦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
順序)。寫\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 write
9 java.io.PrintStream null print
10 java.io.PrintStream null println
11 reflection.StackTrace StackTrace.java main
實例堆棧跟蹤:
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
,我打電話給reflection.StackTrace
的main
方法System.out.println
。
/E2
這11或10的差異似乎是因爲println
呼叫print
和newLine
。 print
繼續呼叫write
,而newLine
直接將新行字符寫入流中。但這不應該因爲該罐子不包含java.io.PrintStream
。
有趣的解決方案...它似乎過於複雜,但我想這可能是唯一的解決方案... – K2xL
如果你有一個更大的PROGRAMM考慮像
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);
}
}
此註冊就可以在不同的班級和關閉切換輸出,同時beeing存在保證能夠打開輸出上更高版本。
您例如通過調用
toggleOutput(false)
在每個方法的開始和
toggleOutput(true)
在每個方法的末尾使用它。
注意:這將停止* all *類的'System.out.println'和'System.out.print'調用。 – Jeffrey
啊是的,我只是問上述答案的作者這個問題......所以沒有辦法隱藏它只有一個特定的文件?我在我的課堂上有一些system.out,我不想隱藏...只是這個罐子的作者.. – K2xL
@ K2xL看到我的回答 – Jeffrey