2010-06-14 7 views
7

я смотрел на чей-то код и увидел, что он неоднократно заявлялНа System.out, разъяснение необходимости

PrintStream out = System.out; 

и позже названный

out.println("blah"); 

Я на самом деле думал, что это был своего рода аккуратно. Это обычная практика? Был ли он просто фантазией?

+6

Он мог бы так же легко добавить объявление import static java.lang.System.out; 'в верхней части файла. – ILMTitan

+0

@ILMTitan - это еще более четкое решение, но, конечно, будет работать только с java 5 и выше. – Alb

+2

@Alb Java 5 уже завершил период окончания службы. –

ответ

7

Это разумный подход. Он в основном создает псевдоним для System.out. Существует ряд преимуществ:

  • Меньше набрав.
  • Легче изменить код для вывода на другой PrintStream.
  • Возможно улучшение производительности, хотя оно будет незначительным.
+0

пункт 1, не менее sysout , который будет вставлять «System.out.println()». Пункт 2, да, но это также означает, что вы можете ошибиться, считая, что «выход» означает System.out.println, потому что так оно и было сделано везде в коде. Он также более явный, например, не использует короткие имена переменных. Пункт 3 - нет. Компиляция умнее вас. НИКОГДА не принимайте решение, основанное на том, что, по вашему мнению, будет делать компилятор, не основываясь на тестировании - ваша догадка почти всегда неправильна, компилятор оптимизируется на основе того, что вы не сложны - при написании максимально возможного кода. –

+0

@Bill K: Компилятор является интеллектуальным, но семантика доступа к полю и локальному доступу к переменной различна, поэтому он не может оптимизировать это в целом. Кто скажет, что println() не изменил значение System.out? (Заключительные поля не так окончательны, как вы думаете - посмотрите на System.setout().) –

+0

@Adam Crume Я полагаю, я должен был сказать, что компилятор + время исполнения умнее, чем вы думаете. Он может посмотреть на то, что System.out не меняет и не строит код для записи на него. Фактически, он может встроить весь блок кода для выполнения фактического вывода, если он захочет - возможно, это не так, но я не был бы слишком удивлен, если бы это произошло. Если бы вы выбрали псевдоним «out», это может помешать такой оптимизации времени выполнения. В принципе, все, что я говорил, это то, что, если вы ВСЕПОНИМИТЕ решение по программированию, основанное на теоретических преимуществах производительности, а не на проверенных преимуществах, вам действительно нужно переосмыслить это. –

0

Это ярлык, если вы делаете много println. я видел это сделано в местах раньше, хотя я, как правило, не делать это, потому что я думаю, что System.out.println понятнее, так как вам не нужно, чтобы выяснить, где out был назначен. Я настраиваю шаблон затмения, чтобы автозаполнять println до System.out.println, и это довольно быстро.

+0

Eclipse имеет встроенный шаблон «sysout», поэтому вам даже не нужно было создавать ваш собственный :) – benjismith

+0

Правда, но я пишу много отличного кода, и таким образом я могу использовать println на любом языке. –

0

Nope. Никогда не видел этого раньше.

Согласен. Это не слишком потрепанный ...

3

Чтобы не вводить System.out.println специально при выполнении небольшого теста (без IDE) Я использую import static java.lang.System.out вместо

Но это может иметь смысл, если вы хотите, чтобы подставить значение System.out позже, возможно, обертку для перенаправления к файлу

PrintStream out = new FilePrintStream("MyLogs.log"); // // System.out 

И отключите стандартный вывод сразу. Повторяю это may имеют смысл в некоторых сценариях, потому что для этого я бы использовал фреймворк регистрации.

Кстати, было бы лучше, чтобы объявить его как окончательное и статические также:

class YourClass { 
    private final static PrintStream out = System.out; 
} 
0

Если посмотреть на Throwable.printStackTrace в документации вы можете вызвать его без аргументов, и он просто передает System.out к версии, которая берет PrintStream.

Общепринято находить ситуации, в которых может быть передано несколько различных объектов PrintStream, что значительно упрощает печать.

0

Это симпатичный трюк, но, как и большинство милых трюков, лучше всего сделать это правильно.

Как только вы доберетесь до точки, в которой вы уверены, что хотите вести журнал (достаточно, чтобы добавить что-то подобное), почему бы просто не получить Log4J или какую-либо другую систему ведения журнала, которая обладает еще большей гибкостью и мощностью?

Чувствительный материал - это мило и весело, если вы одиноки, но даже если вы действительно медленная машинистка, и это сохраняет вас целых 5 секунд каждый раз, когда вы вводите его (через System.out или "sysout +<ctrl-space>" в eclipse/netbeans), вы потеряете это время в десять раз в первый раз, когда кто-то, возможно, вы увидите «вне». и не знает сразу, что это значит.

Я имею в виду, что в одной программе предположим, что вы сделали то, что предложил другой плакат, и перенаправили «выход», чтобы перейти к файлу вместо STDOUT, но в некоторых классах, возможно, «out» по-прежнему идет в System.out. или, может быть, вы просто забыли, что перенаправили его в файл. Позже вы прийти и сказать: «Ну, он говорит:

out.println("WE MADE IT"); 

, но я не вижу, что линия в STDOUT, что ад?»

Затем вы тратите 4 часа на отслеживание плохого показания вместо исправления ошибки.

+0

Если вы использовали Eclipse и видели «out», не могли бы вы просто нажать F3 на нем и посмотреть, где именно он идет, не теряя времени? Я все для удаления дублирования и удаления вызова System.out, где он используется, - это удаление дублирования. Причины хорошо изложены в ответе http://stackoverflow.com/questions/3041482/plain-old-system-out-question/3041495#3041495 – Alb

+0

Нет, если вы не думали об этом, и в этом весь смысл. Явные биты, когда вы работаете с другими. Когда вы одиноки, ваш код может быть таким же забавным, как вам нравится, но я действительно устал работать над другими трюками. Это отношение вызывает некоторую любовь/ненависть с соглашениями об именах переменных Java. Я имею в виду, что вы сохранили бы столько места, используя yalvn, вместо того, чтобы набирать еще одно имя LonVarableName, но некоторые люди начинают понимать важность явного краткого (по крайней мере, в мире Java - я все еще вижу много переменных «yalvn» c имена, как если бы они занимали память или что-то в этом роде) –

+0

Конечно, я ценю достойное имя метода, но в этом случае исходное имя метода просто «вне». Во-первых, я не думаю, что кто-то должен предположить, что это будет System.out без его проверки, во-вторых, я не думаю, что добавление пакета к нему при каждом вызове - лучший способ справиться с этим. Извлечение всех вызовов System.out, например, «printToConsole» или «printToLogStream», лучше, чем оставлять их встроенными, по моему мнению, поскольку оно удаляет дублирование, но сохраняет ясность намерения. – Alb

0

Является ли это хорошей идеей, является спорным и, вероятно, зависит от обстоятельств.

С положительной стороны:

  • Это делает код приложения взгляд аккуратнее.
  • Это может упростить изменение адресата для вывода.

На минус стороне:

  • Это потенциально увеличивает кросс-сочетания; например если переменная out является переменной экземпляра или должна быть передана в качестве параметра.
  • Это потенциально вызывает проблемы, если вашему приложению необходимо позвонить System.setOut().
  • Если код System.out просто отлаживается, это затрудняет уведомление и удаление. Действительно, это, вероятно, сводит на нет проверки качества кода PMD (и т. Д.), Которые сообщают об этом.

Следует отметить, что существуют потенциально другие способы сделать это; например заменяя System.out.println(String) на полезный метод printLine(String) достигает аналогичного эффекта без перекрестного сцепления.

0

с System.out является переменной final, то, что он сделал, будет идентификатором для ссылки System.out.

если только кто-то не назвал System.setOut(), который переназначил System.out.

ждите, что?

1

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

Может быть небольшое преимущество для этого, которое могло бы иметь возможность изменять выходной поток, если это необходимо, в файл, сокет или что-то еще.Таким образом, он сможет заменить:

PrintStream out = System.out; 

с

PrintStream out = new PrintStream(new FileOutputStream(filename)); 

Однако, если он повторно объявить его снова и снова, он действительно теряет выше преимущество, потому что весь смысл будет иметь он где-то централизован и решает, где вывести журналы в одном месте.

Обратите внимание, что это очень грубый способ, и реальной стандартной практикой является использование журнала. Java имеет свой собственный пакет java.util.logging из коробки, log4j - еще одна очень мощная альтернатива (и очень популярная), и есть другие.

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

  • Нет связанных вопросов^_^