System.out.println ()을 사용하는 것이 왜 그렇게 나쁜가요? [닫은]


18

물론 오류 메시지 나 경고에 로깅 프레임 워크를 사용하는 것이 좋습니다. 그러나 짧은 시간 안에 새로운 것을 시도하고 싶다면 때때로 System.out.println ()을 사용합니다.

빠른 테스트를 위해 System.out.println ()을 사용하는 것이 정말 좋지 않습니까?


3
아니요. 빠른 테스트입니다. 누가 걱정합니까?
Bryan Boettcher

10
누가 나쁜가요? 대안은 무엇입니까?
James

1
@Kayser 정적 코드 검토 도구는 빠른 테스트에 적합하지 않습니다. 다른 사용자와 함께 개발하려는 코드 (또는 다른 사람들이 이해해야하는 코드)에 더 적합합니다. 내가 올해 배우고있는 교훈은 심지어 업무 시간 내내 매우 다른 툴셋과 실습이 필요한 매우 다른 문제 공간이 있다는 것입니다. 따라서 빠른 테스트를 위해 모두 척하고 Groovy를 사용하십시오.
Bill K

1
사용 System.err.println()하고 어떻게되는지 보십시오 . 도구가 System.out잘못된 목적으로 사용한다고 생각합니다 .
이즈 카타

2
주요 문제는 확장 성과 제어에 있습니다. 수백만 건의이 진술이 있다면 어떻게 볼 필요가 있는지 알 수 있습니다. 이 중 하나에 반응해야 할 경우 프로그래밍 방식으로 어떻게 할 수 있습니까? 로깅 프레임 워크는 일반적으로 System.out에 적용되는 두 가지 생각입니다.

답변:


18

주석에서 알 수 있듯이 실제 질문은 왜 정적 코드 분석 도구가 System.out.println의 사용을 플래그 지정합니까?입니다.

stdout에 메시지를 보내는 것은 일반적으로 프로덕션 환경에서 부적절하기 때문입니다. 라이브러리를 코딩하는 경우 라이브러리는 stdout으로 인쇄하지 않고 호출자에게 정보를 반환해야합니다. GUI 앱을 코딩하는 경우 stdout이 가리키는 위치가 아닌 사용자에게 정보를 제공해야합니다. 서버 (또는 서버 측 컨테이너에서 실행되는 코드)를 코딩하는 경우 프레임 워크가 제공 한 모든 로깅 기능을 사용해야합니다. 기타 등등.

그러나 디버깅 또는 개발을 위해 println을 사용하거나 프로그램을 작성하고 stdin을 읽고 stdout에 쓰는 경우 println이 완벽하게 좋습니다. 이런 종류의 경우에는 아무런 문제가 없습니다.


3
좋은 대답입니다. 감사합니다 .. +1 "GUI 앱을 코딩하는 경우 stdout이 가리키는 위치가 아닌 사용자에게 정보를 제공해야합니다."
Kayser

10

모든 stdout버퍼링, 따라서이다 가능한 프로그램이 충돌 것 당신이라고 println()하지만, 전에 가 화면에 도달합니다.

그렇게 말하면이 시나리오는 실제로 가능성이 거의 없습니다. 계속해서 사용하되, 마음의 사소한 제한을 유지하십시오.


적어도 두 개의 주요 파이썬 인터프리터는 종료가 처리되지 않은 예외로 인한 경우에도 종료 전에 열려있는 모든 파일을 플러시하려고 매우 열심히 노력합니다. JVM이 비슷한 것을하지 않습니까?

1
@delnan, 가능하지만 모든 일이 발생할 수 있습니다. (stdout을 플러시하는 코드는 문제가있는 곳 일 수 있습니다. 실행중인 스레드가 강제로 닫힐 수 있습니다. 현재 프로세스는 OS에 의해 메모리에서 강제로 덤프 될 수 있습니다.) 내 성명에 따라 생활하지 마십시오. 그냥 알아 둬
riwalk

1
stdout을 플러시하는 코드는 VM 자체에 있으므로 VM이 구현하는 언어의 오류에 영향을받지 않습니다. 강제 프로세스 종료에 대한 좋은 지적. 그러나 예를 들어 Unix의 SIGTERM 및 대부분의 다른 신호는 이와 같이 정리하기 위해 잡힐 수 있습니다. 더 극단적 인 SIGKILL에서는 작동하지 않습니다.

2
나는 다른 문제를 보았지만 이것을 보았거나 그것이 일어난 것을 들었다고 생각하지 않습니다. 이 문제는 System.out을 기본 도구로 사용하기 때문에 로거와 같은 도구로는 더 나아지지 않을 것입니다.
Bill K

@delnan 정리 코드가 반드시 실행된다고 가정하지 말고 최종 블록에 중요한 비즈니스 트랜잭션 코드를 넣지 마십시오.;) System.out은 디버깅에 적합하지만 버퍼링에주의하십시오.
Steven

8

System.out그냥 포장 BufferedOutputStream입니다. 이것은 사용하는 로깅 프레임 워크와 유사 할 수 있습니다. 프레임 워크는 구성 및 로그 출력 대상의 형태로 더 많은 기능을 제공합니다.


4
이것은 실제로 질문에 대답하지 않습니다. "나쁜가요?"
sergserg

@Berg-질문의 해당 부분은 상황에 따라 완전히 달라지기 때문입니다. (또는 그냥 아니에요, 나쁘지 않습니다)
spinning_plate

7

사소하지 않은 프로그램을 작업하고 있다면 나쁘다

  • 자동화 된 단위 테스트 (JUnit) 대신 System.out을 버팀목으로 사용
  • System.out 문을 작성, 삭제 또는 주석 달기 / 주석 해제하는 데 많은 시간을 소비하십시오.

1
대부분의 IDE에는 System.out.println을 자동 완성하고, 줄을 주석 처리하거나 주석 해제하고, 줄을 삭제하기위한 단축 키가 있어야합니다. 원칙적으로 과도한 사용을 피하는 것이 옳지 만 적어도 이런 식으로 시간을 절약 할 수 있습니다.
Steven

7

System.out버리기 코드에서도을 사용하는 것에 대한 몇 가지주의 사항이 있습니다 .

한 가지 큰 문제는 보통 느리다는 것 입니다. 예를 들어, 일부 코드의 속도에 대한 대략적인 아이디어를 얻으려고하는 경우 ( 마이크로 벤치 마크는 어렵다는 점에 유의하십시오 ) System.out.println()어디에서나 단일 코드 를 추가하면 타이밍이 엉망이 될 수 있습니다 (동기화되고 실제 출력을 기다리는 경우가 많기 때문에) 반환하기 전에 사용자에게 표시됩니다.

그 외에는 일회용 코드에서 그것에 대해 너무 걱정하지 않아도됩니다. 커밋하려는 경우 (프로덕션 코드 또는 테스트 코드로)이를 제거하고 적절한 로깅 호출 (예 : 테스트 코드 에서도) 로 바꾸어야 합니다.


성능은 좋은 논쟁입니다.
Kayser

4

종종 그렇듯이 대답은“의존적”입니다. 응용 프로그램에 이미 로깅 프레임 워크가있는 경우에도 사용할 수 있습니다. 이보다 성능이 떨어질 수 없으며 println()스택 추적, 추가 컨텍스트, 더 나은 형식 지정 등과 같은 다른 기능을 활용할 수도 있습니다. 로깅 프레임 워크가 더 나은 오류 복구를 제공하여 치명적인 오류 발생시에도 로그가 성공적으로 작성되도록하는 확실한 가능성도 있습니다.

따라서 언제부터 로깅 시스템을 추가해야하는지에 대한 의문이 생깁니다. 이것은 판단 요청입니다. 너무 일찍 추가하고 싶지 않으며 실제로 필요하지 않다는 것을 알기 위해서입니다. 또한 너무 늦게 추가하고 싶지 않으며 임시 솔루션에서 과도한 작업을 변환해야합니다.

로 많은 로깅을 수행하고 있음을 발견하면 println()코드베이스가 점점 더 많은 고통을 겪고 있음을 알려줍니다. 그 시점에서 적절한 벌목에 투자하는 것이 좋습니다.


3

System.out.print가 "시스템 기본"코드 페이지를 사용한다는 문제가 종종 있습니다. "시스템 기본"코드 페이지는 Linux에서는 종종 UTF-8이지만 일부는 Windows에서는 잘립니다.

프로그램이 실행되는 위치에 따라 유니 코드 문자가 화면에 올바르게 인쇄되거나 인쇄되지 않을 수 있습니다.

따라서 System.out보다 사용자 정의 PrintWriter를 선호합니다.


박힌 MS 물건으로. CP1352 또는 UTF16을 의미합니까?
Cole Johnson

@ColeJohnson : 불행히도 Windows 콘솔 창이 여전히 UTF16 이전 시대에 갇혀 있습니다. 그러나 콘솔이 내장 된 정상 IDE를 사용하면 문제를 줄일 수 있습니다.
Joachim Sauer

@Cole Johnson-CP 65001 (예 : utf8)과 함께 사용할 수 있지만, 예를 들어 독일어 키보드를 사용하는 경우 CP 850 또는 그와 같은 것을 얻을 때이를 "시스템 기본"코드 페이지로 가져올 수있는 방법이없는 것 같습니다.
Ingo

1

전혀 나쁘지 않습니다. 이 개념은 애플리케이션에서 전용 로깅 프레임 워크를 사용하는 것만 큼 매우 단순하고 정교하지 않다는 사실에서 비롯 될 수 있습니다.

그러나 이것이 잘못된 접근법이라고 말하는 것은 아닙니다. 나는 검은 마술 부두 프로그래밍 hijinks 후 응용 프로그램 흐름을 확인하기 위해 여러 번 사용했습니다 .


0

그것을 사용하는 데 아무런 문제가 없습니다. '지옥이 어떻게되고 있는지'를 알아내는 데 도움이됩니다.

그러나 동료 / 다른 개발자 / 도구가 당신을 조롱한다면, 항상 Logger를 사용 하거나 Junit 테스트를 시작할 수 있습니다 !


0

내가 본 것처럼 occational System.out.println의 가장 큰 문제는 "나쁜 습관 냄새 (tm)"라는 것입니다. 이 작업을 수행하는 경우 선호하는 디버거를 사용하여보다 편안하게 효과를 향상시킬 수 있습니다.

또한 디버거를 사용하면 System.out.println이 중단되는 동안 중단 점이 프로덕션 코드에 들어 가지 않는다는 것을 알고 있습니다.

참고로, 실제로 빠른 테스트를 수행하고 디버거를 사용하지 않고 지속되는 경우 System.out.println이 로깅 프레임 워크를 사용하는 것보다 낫다고 생각합니다. 끝났습니다. 뿌리 뽑기가 더 어렵습니다.


0

내부 상태의 내용을 반향하는 것에 대한 전체 테스트 전략을 세우는 것이 가장 현명한 방법은 아니지만 개발 과정에서 빠르고 더러운 코드 테스트를 위해 여기에서 이상한 println을 사용하면 제거 할 때까지 상처를 입지 않습니다!

그것들을 제거하는 것을 잊어 버릴 수있는 위험은 아마 그것이 권고 된 이유 일 것입니다.


당신의 의견으로는 그것들을 제거하는 것을 잊어 버릴 때의 문제점은 무엇입니까? 콘솔에 더 많은 메시지가있을 것입니다. 다른 문제가 있습니까?
Kayser
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.