Java 在system.out.println的代码中查找位置

Java 在system.out.println的代码中查找位置,java,reflection,Java,Reflection,假设我在一个非常大的项目中工作,注意到一个空的打印行,所以我假设有一个System.out.println(“”);位于代码的某个地方。除了在整个项目中搜索System.out.println的所有实例之外,我该如何尝试找出它的位置?您可以实现自己的PrintStream并使用System.setOut替换默认的标准输出。然后在类中放置调试标记(如果打印的是空字符串),或者通过调用堆栈打印出方法名称(抛出并捕获异常并获取堆栈信息)。这也可能是由于库中的某些内容造成的,如果您觉得这只是因为Syst

假设我在一个非常大的项目中工作,注意到一个空的打印行,所以我假设有一个System.out.println(“”);位于代码的某个地方。除了在整个项目中搜索System.out.println的所有实例之外,我该如何尝试找出它的位置?

您可以实现自己的
PrintStream
并使用
System.setOut
替换默认的标准输出。然后在类中放置调试标记(如果打印的是空字符串),或者通过调用堆栈打印出方法名称(抛出并捕获异常并获取堆栈信息)。

这也可能是由于库中的某些内容造成的,如果您觉得这只是因为System.out.println

解决方案1: 下面的代码片段应该可以帮助您找到执行它的位置

        import java.io.FileNotFoundException;
        import java.io.PrintStream;

        public class CustomPrintStream extends PrintStream {

        public CustomPrintStream(String fileName) throws FileNotFoundException {
            super(fileName);
        }

            @Override
            public void print(String s) {

                try{
                    if(s == null || s.equals("")){
                        throw new Exception("Invalid print message");
                    }
                    super.print(s);
                }catch(Exception e){
                    //TODO Change to your logger framework and leave it as same 
                    e.printStackTrace();
                }
            }

            public static void main(String[] args) {
                try {
 //TODO : Change to your favorite path and make sure mentioned
//file is available
                    CustomPrintStream customPrintStream = new CustomPrintStream
    ("/home/prem/Desktop/test.log");
                    System.setOut(customPrintStream);
                    System.out.println("");

                } catch (FileNotFoundException e) {
                    //TODO Change to your logger framework and leave it as same 
                    e.printStackTrace();
                }
            }
        }
解决方案2: 由于IDE是可用的,请向他们寻求帮助 菜单->搜索->文件搜索->放置系统.out.println(“”);在包含搜索和搜索它

我宁愿说不要在任何代码中使用System.out.println,因为您可以使用checkstyle,并确信没有开发人员使用它们。

如果您使用Java 8+,则有一个类可以轻松找到打印给定行的位置:

StackDumper.dumpWhenSysOutContains("SomeTrigger")
当打印“SomeTrigger”时,它将转储到
系统。err

+----------\
| Triggered by SomeTrigger
| at package.MyClass.myMethod(MyClass.java:62)
| (the rest of the stacktrace)
+----------/
对于您的情况(查找空字符串),它有点复杂:

PrintStream sysOutClean = System.out;
StringPrinter sysOutReplacement = new StringPrinter(StringPrinter.stringsToLines(line -> {
    if (line.isEmpty()) {
        StackDumper.dump("Found empty line");
    }
    sysOutClean.println(line);
}));
System.setOut(sysOutReplacement.toPrintStream());
现在如果有这样的事情:

System.out.println("ABC");
System.out.println("123");
System.out.println("");
System.out.println("DEF");
ABC
123
+----------\
| Found empty line
| at package.MyClass.myMethod(MyClass.java:62)
| (the rest of the stacktrace)
+----------/

DEF
然后,您的控制台将如下所示:

System.out.println("ABC");
System.out.println("123");
System.out.println("");
System.out.println("DEF");
ABC
123
+----------\
| Found empty line
| at package.MyClass.myMethod(MyClass.java:62)
| (the rest of the stacktrace)
+----------/

DEF
例如:

只需调用以下类的方法,这有助于开发人员控制sysout

*@作者Dharmendrasinh Chudasama */ 公共类SysOutController{ 专用静态无效放样(OutputStream out){ 系统放样(新打印流(out)); } 私有静态最终输出流控制台=新的FileOutputStream(FileDescriptor.out); /** *重置系统输出打印*方法 *@作者Dharmendrasinh Chudasama */ 公共静态void resetSysOut(){setOut(控制台);} /** *System.out.print*不会在控制台中打印任何内容 *@作者Dharmendrasinh Chudasama */ 公共静态void ignoreSysout(){ 放样(新输出流(){ @重写公共无效写入(int b)引发IOException{} }); } /** *调用System.out.*方法的地址/位置将附加到控制台中 *@作者Dharmendrasinh Chudasama */ 公共静态无效设置SysoutLocationAddressor(){ 放样(新输出流(){ @凌驾 公共无效写入(int b)引发IOException{ if(b=='\n'){//if换行符 final StackTraceElement callerStEl=new Throwable().getStackTrace()[9]; 字符串路径数据= “\u001B[37m”//低可视性 +“\t::(“+callerStEl.getFileName()+”:“+callerStEl.getLineNumber()+”[“+callerStEl+”]”//代码路径 +“\u001B[0m”//重置 write(pathData.getBytes()); } 控制台。写入(b); } }); } }
定义一个类NewPrintStream扩展了PrintStream

System.setOut(new NewPrintStream("aaa"));
System.setErr(new NewPrintStream("aaa"));
然后在主类中设置stdout/stderr打印流


PrintStream.println(字符串x)
中放置一个条件断点,条件设置为
x.equals(“”)
或任何字符串。

在整个项目范围内搜索System.out.println..您是否使用Eclipse之类的IDE?是的,但我正在尝试找到更好的方法,因为这种情况似乎经常发生,而且整个代码库中有大量的syso。听起来您需要在整个项目范围内进行“调试”机制..并且您希望完全删除System.out.println(在您实现的“debug”类或“output”类之外。是否有一种方法可以在不引发异常的情况下获取该类?异常仅用于获取stacktrace(尽管应该有一种更直接的获取方法)。这详细介绍了一种毫无例外的方法。谢谢!这非常适合查找其他人不必要地添加的打印行,并且没有任何我可以搜索的文本(只是将一个对象传递给字符串)。关于我如何使用榴莲而不使用Maven的无耻插件:
System.setOut(new NewPrintStream("aaa"));
System.setErr(new NewPrintStream("aaa"));