Чому використання System.out.println () так погано? [зачинено]


18

Звичайно, дуже корисно використовувати рамку реєстрації для повідомлень про помилки або попередження. Але іноді я використовую System.out.println (), якщо хочу спробувати щось нове за короткий час.

Невже так погано використовувати System.out.println () для швидкого тестування?


3
Ні. Це швидкий тест, кого хвилює?
Брайан Боттчер

10
Хто каже, що це погано? Яка альтернатива?
Джеймс

1
Інструменти для перегляду статичного коду @Kayser непридатні для швидких тестів - вони скоріше для коду, який ви маєте намір розробити разом з іншими (або того, що інші повинні зрозуміти). Урок, який я, мабуть, вивчив цього року, полягає в тому, що існують дуже різні простори, навіть протягом робочого дня, які вимагають дуже різних наборів інструментів та практик. Тож для вашого швидкого тестування, зафіксуйте все це та використовуйте Groovy :)
Білл К

1
Спробуйте скористатися System.err.println()і побачити, що станеться. Я здогадуюсь, що інструмент вважає, що ви використовуєте System.outдля неправильних цілей.
Ізката

2
Основна проблема полягає в масштабованості та контролі. Якщо у вас є мільйони цих тверджень, як ви можете бачити те, що вам потрібно бачити. Якщо вам потрібно відреагувати на одне із них, як це зробити програмно. Рамки ведення журналу зазвичай є тими двома думками, застосованими до System.out.

Відповіді:


18

Як виявлено в коментарях, справжнє питання, яке задається, полягає в тому, чому інструменти для аналізу статичного коду використовують System.out.println?

Причина полягає в тому, що надсилання повідомлень в stdout зазвичай недоцільно у виробничих умовах. Якщо ви кодуєте бібліотеку, бібліотека повинна повертати інформацію своєму абоненту, а не друкувати в stdout. Якщо ви кодуєте додаток для графічного інтерфейсу, інформація повинна бути надана користувачеві, а не там, де stdout вказує (що може нікуди не бути). Якщо ви кодуєте сервер (або щось, що працює в контейнері на сервері), ви повинні використовувати будь-який засіб реєстрації, який рамки надали. І так далі.

Але якщо ви використовуєте println для налагодження або розробки, або ви пишете програму і читаєте stdin і пишете в stdout, println - це прекрасно. У цьому немає нічого поганого для таких випадків.


3
Гарна відповідь. Дякую .. +1 за "Якщо ви кодуєте додаток для графічного інтерфейсу, інформацію слід подавати користувачеві, а не туди, куди вказує stdout (що може бути нікуди)"
Kayser

10

Усі stdoutє захищеними, і, таким чином, можливо , ваша програма вийде з ладу після того, як ви подзвонили println(), але до того, як вона вийде на екран.

Зважаючи на це, цей сценарій дійсно малоймовірний. Ідіть і використовуйте його, але просто тримайте це незначне обмеження в задній частині розуму.


Принаймні два основні інтерпретатори Python дуже важко намагаються промити всі відкриті файли перед виходом, навіть якщо вихід через нерегламентований виняток. Хіба співавтори не роблять щось подібне?

1
@delnan, Можливо, але все може статися. (Код, який вимиває stdout, може бути там, де проблемні поверхні. Нитка, в яку ви працюєте, може бути насильно закрита. Поточний процес може бути насильно скинуто з пам'яті ОС.) Не живіть своїм життям навколо мого твердження, але просто знайте про це.
riwalk

1
Код, який змиває stdout, знаходиться у самому VM, і таким чином не впливає на помилки в мові, яку реалізує VM. Хороший момент щодо примусового завершення процесу Але зауважте, що, наприклад, SIGTERM Unix та більшість інших сигналів можуть бути схоплені для очищення, як це - не працює з більш екстремальними SIGKILL.

2
Я не думаю, що я ніколи не бачив цього і не чув, щоб це відбувалося, хоча я бачив інші проблеми. Ця проблема також не покращиться з такими інструментами, як реєстратори, оскільки вони, ймовірно, використовують System.out як основний інструмент.
Білл К

@delnan Ніколи не вважайте, що ваш код очищення гарантовано працює ... і ніколи не ставити критичний код бізнес-транзакцій остаточно блокується;) System.out чудово підходить для налагодження, але будьте в курсі буферизації.
Стівен

8

System.outце просто загорнута BufferedOutputStream. Це, мабуть, схоже на будь-який фреймворк ведення журналу, який ви будете використовувати, рамки просто забезпечують більше функціональних можливостей у вигляді конфігурації та призначення вихідного журналу.


4
Це насправді не відповідає на питання. "Це погано?"
сергсерг

@Berg - Тому що ця частина питання повністю залежить від контексту. (або просто, ні, це не погано)
spinning_plate

7

Погано, якщо ти працюєш над нетривіальною програмою і ти

  • Використовують System.out як милицю замість автоматизованого тестування блоку (JUnit)
  • Витратьте багато часу на створення та видалення або коментування / коментування виписок System.out

1
Більшість IDE повинні мати гарячі клавіші для автоматичного завершення System.out.println, коментування / коментування рядка та видалення рядка. Ви в принципі праві, щоб намагатися уникати надмірного використання, але таким чином ви можете принаймні заощадити час.
Стівен

7

Існує кілька застережень щодо використання System.outнавіть у викиданні коду.

Одна з основних проблем полягає в тому, що це зазвичай повільно . Наприклад, якщо ви намагаєтеся отримати приблизне уявлення про швидкість деякого коду (зауважте, що мікробензикові показники важкі ), то додавання єдиного System.out.println()місця може дійсно зіпсувати ваш час (адже це синхронізується і часто чекає, коли фактичний вихід буде бути видимим для користувача перед поверненням).

Крім цього, я б не переживав про це в коді, що викидається. Якщо ви маєте намір скористатись ним (будь то виробничий код або як тестовий код), вам слід позбутися його та замінити його викликом реєстрації протоколу (так, навіть у тестовому коді).


Виступ - хороший аргумент ..
Кейсер

4

Як це часто буває, відповідь - це "залежить". Якщо у вашій програмі вже встановлена ​​система реєстрації журналів, то ви також можете використовувати її. Він не може бути менш здатним, ніж вам println(), і ви можете скористатися іншими функціями, які він надає - стеком стежок, додатковим контекстом, кращим форматуванням тощо. Існує також чітка можливість того, що рамки реєстрації пропонують краще відновлення помилок, забезпечуючи успішне записування ваших журналів навіть у випадку катастрофічного збою.

Тож виникає питання, коли в першу чергу додати систему каротажу. Це виклик вирок: ви не хочете додавати його занадто рано, аби тільки з'ясувати, що в ньому насправді немає потреби. Ви також не хочете додавати його занадто пізно і робити надмірну роботу, перетворюючись на своєчасне рішення.

Якщо ви виявите, що ви робите багато журналів println(), ваша кодова база намагається сказати вам, що відчуває зростаючі болі. У цей момент варто інвестувати в правильний лісозаготівлю.


3

У мене часто виникає проблема, що System.out.print використовує кодову сторінку "системного за замовчуванням", яка часто є UTF-8 під Linux, але деякі зламані матеріали MS під Windows.

Це може призвести до унікодування символів, які неправильно надруковані на екрані, залежно від того, де програма працює.

Тому я віддаю перевагу користувальницький PrintWriter над System.out


По зламаному МС. Ви маєте на увазі CP1352 або UTF16?
Коул Джонсон

@ColeJohnson: Вікно консолі Windows, на жаль, все ще застрягло в епоху до UTF16. Однак використання розумного IDE із вбудованою консоллю може зменшити цю проблему.
Йоахім Зауер

@Cole Johnson - я міг би жити з CP 65001 (тобто utf8), але, схоже, немає способу отримати це кодовою сторінкою як "системний за замовчуванням", коли, наприклад, у вас є німецька клавіатура, ви отримуєте CP 850 або щось подібне.
Інго

1

Це зовсім не погано. Поняття може випливати з того, що він дуже простий і не такий складний, як використання спеціальної системи реєстрації журналів у вашій програмі.

Однак це не означає, що це недійсний підхід. Я багато разів використовував це для перевірки потоку додатків після деяких чорних магічних програмувань вуду .


0

В цьому немає нічого поганого, це допомагає вам зрозуміти, "що, до біса, відбувається".

Але якщо ваші колеги / інші розробники / інструменти висміюють вас, ви завжди можете використовувати Logger або почати тестування Junit !


0

Як я бачу, найбільша проблема з професійною системою.out.println полягає в тому, що це "поганий запах звички (тм)". Якщо ви виявите, що це робите, то, ймовірно, ви могли б підвищити свою ефективність, зробивши більш комфортним використання улюбленого налагоджувача.

Крім того, з налагоджувачем ви точно знаєте, що точка пробою не скотиться у ваш виробничий код, тоді як System.out.println може.

Зі сторони, якщо ви насправді просто робите швидкий тест і наполягаєте на тому, що не використовуєте налагоджувач, я думаю, що System.out.println краще, ніж використовувати рамку реєстрації, оскільки якщо ви випадково залишите оператор log.debug, коли ви Зроблено, важче вирватися.


0

Побудова цілої стратегії тестування навколо повторення вмісту внутрішнього стану - це не найрозумніший крок, але для швидких і брудних тестів коду в розробці незвичайний println тут і не зашкодить, поки ви пам’ятаєте їх видалити!

Небезпека забути їх видалити, ймовірно, тому не рекомендується.


Яка проблема із забуттям видалити їх, на вашу думку? Впевнені, що на консолі буде ще кілька повідомлень. Чи бачите ви якусь іншу проблему?
Кайсер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.