2009-02-21 1 views
9

У нас есть огромная (старая устаревшая java) база кода, где у многих файлов (около 5k) есть System.out.println. Мы планируем удалить их по соображениям очистки/производительности. Как мы можем написать скрипт, который заменит их, не введя никаких проблем в код? Сценарий не может слепо удалить их следующим образом дело может быть проблема:Как удалить System.out.println из codebase

if() 
    some.code... 
else 
    System.out.println(...); 
DB.close(); 

Я подумываю заменить их «;». Это позаботится об этом. Вы видите другие проблемы? Любые другие предложения?

+0

pontificate mode on :-) Это (среди многих других причин), почему я всегда использую {} даже для одной строки! (Я знаю, что это наследие и, скорее всего, не твоя работа). Я заменил бы их вместо {}; но оба они в порядке. – TofuBeer

+0

Pontificate echo on: Я собирался прокомментировать то же самое. –

+0

Я знаю, и это может быть не в коде. Однако, поскольку есть много файлов и наследия (что почти всегда означает «плохо»), я не хочу рисковать. – amit

ответ

24

Вы рассмотрим глупый случай:

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

Я не думаю, что это произойдет, но есть вероятность, Println выполняет метод, который фактически выполняет какое-то действие, на которых система зависит и может ввести тонкие ошибки (поверьте мне или нет, но я был свидетелем этого)

Возможно, замена регистратором и отключение регистраторов могут быть выполнены.

Или создать нулевой объект, используя шаблон NullObject:

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) {} 

    }); 
} 

И замена

System.out.println(); 

С

DevNull.out.println(); 
+0

Мне это очень нравится, Оскар. Ну, подумал, должен сказать. –

+0

Потрясающе, мне пришлось вырваться из NetBeans и попробовать. – Paxic

+0

Хорошая идея - было бы еще проще увидеть, изменили ли вы «глупый случай» с объекта object.stateChanged() на object.changeState(), иначе это будет похоже на запрос к объекту, который я всегда рассматриваю как не меняющий бизнес состояния объектов. ... личная привычка ... –

1

Лично я бы использовал {} вместо этого, но я думаю, что он работает точно так же.

2

Вы можете использовать conditional compilation иметь отладки строить с распечатывать заявления и выпускать без них.

В принципе, идея состоит в том, чтобы создать окончательный статический класс с конечным статическим булевым, который вы используете в качестве коммутатора во время компиляции.

public final class Debug { 
    //set to false to allow compiler to identify and eliminate 
    //unreachable code 
    public static final boolean ON = true; 
} 

Тогда вы можете просто заменить все ваши System.out.println заявления с

if(Debug.ON) 
{ 
    System.out.println... 
} 

Поскольку компилятор будет игнорировать любые недостижимые ветви кода, вы можете просто установить ON = false когда вы делаете релиз сборки и печать операторы будут исключены из вашего байт-кода.

Примечание: Это не относится к случаю, когда указал Oscar, где оператор печати может изменять состояние какого-либо объекта. Вы можете использовать условную компиляцию для печати на нулевом объекте, когда в режиме выпуска, как он предположил, вместо того, чтобы полностью удалять отпечатки.

11

Log4E - это плагин eclipse с функцией «Заменить System.out.println()». Он с радостью преобразует все эти досадные вызовы println в вызовы log4j. Он даже обернет их проверкой уровня журнала.

+3

ссылка: http://log4e.jayefem.de/ –

6

Вы можете начать с вызова Systems.setOut и передать свой собственный OutputStream, который ничего не делает. Это поможет вам понять, есть ли прирост производительности. Это безопаснее, чем удаление их (по той причине, что Оскар указал - кодирование побочным эффектом).Если прирост производительности пренебрежимо мал, вы можете сосредоточить свои усилия в другом месте.

Два вопроса с моим выше способом:

  1. любые System.out.printlns вы хотите сохранить будет disapper слишком
  2. струнный concatination будет по-прежнему иметь место (и это может быть дорогим в зависимости от того, насколько есть)

Однако это хороший быстрый тест, чтобы узнать, получаете ли вы прирост производительности, который вы ищете.

0

Я написал регулярное выражение в perl, которое заменяет строку «System.out.println» на «; // System.out.println». Я считаю, что очень мало случаев, когда это нарушит сборку. Он просто станет «else», который скомпилирован в нулевые инструкции байт-кода.

Похоже, это то, что вы предложили. Это сработало для меня, за исключением случаев, когда у вас есть дополнительные инструкции в одной строке. Однако это плохой стиль для начала (и я знал, что я этого не делал).

8

Расширение концепции Оскара вы можете сделать даже лучше ИМХО:

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) {} 

     }); 
    } 
} 

В этом случае, если вы не в режиме отладки или любой другой системы по умолчанию из заменяется внутренне с реализацией devNull, иначе он работает как ожидается. Таким образом, вам не нужно ничего находить и заменять в своем коде.

+0

Интересно. Новые операторы печати могут обрабатываться регистраторами и полностью отключать System.out. :) – OscarRyz

+0

Итак, можно ли назвать этот подход «Оскар Рейес + Билл Ящерицей»? : P: P +1 для этого – OscarRyz

+0

Это не предполагает, что никакой другой код уже делает setOut;) Просто шучу. Это хорошее предложение. – amit

0

Рассматривали ли вы редактирование этих исходных файлов для удаления строк?

Возможно, вы обнаружите, что через пару дней вам будет только разработчик и избавиться от большинства из них. У нас была аналогичная проблема, и я только что встал очень рано и просмотрел все наши файлы, избавляясь от мусора.

Я использовал Eclipse и функцию очистки на сохранении для очистки и импорта в одно и то же время.

Его довольно терапевтическая вещь!

Смежные вопросы