How to remove System.out.println's from codebase

前端 未结 8 1415
天涯浪人
天涯浪人 2020-12-15 11:26

We have a huge (old legacy java) code-base, where many files (around 5k) have System.out.println\'s. We are planning to remove them for cleanup/performance reasons. How can

相关标签:
8条回答
  • 2020-12-15 11:36

    Extending Oscar's concept you can do even better IMHO:

    if(!DEBUG) {
        System.setOut(
            new PrintStream(new OutputStream() {
                public  void    close() {}
                public  void    flush() {}
                public  void    write(byte[] b) {}
                public  void    write(byte[] b, int off, int len) {}
                public  void    write(int b) {}
    
            } );
        }
    }
    

    In this case, if you are not in debug mode or any other the default system out is replaced internally with devNull implementation, else it works as expected. This way you do not have to find and replace anything in your code.

    0 讨论(0)
  • 2020-12-15 11:40

    Log4E is an eclipse plugin that has a "Replace System.out.println()" feature. It will happily convert all those pesky println calls to log4j calls. It will even wrap them with a log level check.

    0 讨论(0)
  • 2020-12-15 11:52

    You could start by calling Systems.setOut and passing in your own OutputStream that does nothing. That will help you see if there is a perfomance gain. This is safer than removing them (for the reason that Oscar pointed out - coding by side effect). If the performance gain is negligable then you might want to focus your efforts elsewhere.

    Two issues with my above method:

    1. any System.out.printlns you want to keep will disapper too
    2. the String concatination will still take place (and that can be expensive depending on how much there is)

    However it is a good quick test to see if you get the performance gains you are looking for.

    0 讨论(0)
  • 2020-12-15 11:52

    I wrote a regex in perl that replaces the string "System.out.println" with ";//System.out.println". I believe that there are very few cases where this would break the build. It would just become an "else ;", which is compiled to zero bytecode instructions.

    It looks like this is what you've proposed. It worked for me -- except if you have additional statements on the same line. However, that is bad style to begin with (and I knew I didn't do that).

    0 讨论(0)
  • 2020-12-15 11:58

    Personally I would use {} instead, but I think it works just the same.

    0 讨论(0)
  • 2020-12-15 12:00

    Have you consider the silly case:

    System.out.println(" Print " +  object.changeState() );
    

    I don't think it happen but chances are the println executes a method that is actually performing some action on which the system depends on and may introduce subtle bugs ( believe me or not, but I have witnessed this )

    Probably replacing with a logger and disabling the loggers may do.

    Or creating a null object using the NullObject pattern:

    public final class DevNull { 
        public final static PrintStream out = new PrintStream(new OutputStream() {
            public void close() {}
            public void flush() {}
            public void write(byte[] b) {}
            public void write(byte[] b, int off, int len) {}
            public void write(int b) {}
    
        } );
    }
    

    And replacing

     System.out.println();
    

    With

     DevNull.out.println();
    
    0 讨论(0)
提交回复
热议问题