System.out.println 질문있습니다.

조회수 1712회

System.out.println()를 뜯어보고 있습니다. System 이라는 객체안에 PrintStream으로 선언된 객체 out에 접근하여 PrintStream의 메소드인 println을 접근 하는 것 까지는 알겠습니다.

근데, System에서 out을 선언할 때, public static final PrintStream out = null; 로 선언하고 끝입니다.

그럼 out은 객체가 생성되지 않은 상태인데 println을 접근 할 수 있는걸 보면(println이 static메소드도 아니고) 어느 부분에서 객체가 생성이 된다는 의미같은데 어느곳인지 알 수 있을까요?

아니면 제가 혹시 잘못 알고 있는걸까요?

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    안녕하세요 찾아보니깐 Out은 PrintStream의 인스터스라네요

    java.io.PrintStream 을 보면 생성자에서 this() 나 super()를 통해 out을 건드립니다. 근데 그 out의 구조는 OutputStream 에서 부터 오네요.

    java.lang.Object
     ㄴ java.io.OutputStream
          ㄴ java.io.FilterOutputStream
                ㄴ java.io.PrintStream
    

    FilterOutputStream 을 까보니

    public class FilterOutputStream extends OutputStream {
    
        protected OutputStream out; //여기
    
        private volatile boolean closed;
    
        private final Object closeLock = new Object();
    
        public FilterOutputStream(OutputStream out) { 
              this.out = out; //여기
        }
    

    PrintStream을 까보니

    public class PrintStream extends FilterOutputStream implements Appendable, Closeable
    {
    
      67     private final boolean autoFlush;
      68     private boolean trouble = false;
      69     private Formatter formatter;
    
      75     private BufferedWriter textOut;
      76     private OutputStreamWriter charOut;
    
     107   private PrintStream(boolean autoFlush, OutputStream out) {
     108         super(out); //여기
     109         this.autoFlush = autoFlush;
     110         this.charOut = new OutputStreamWriter(this);
     111         this.textOut = new BufferedWriter(charOut);
     112     }
     113
    
     119     private PrintStream(boolean autoFlush, Charset charset, OutputStream out) {
     120         this(out, autoFlush, charset); //여기
     121     }
    

    참고: https://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html

    수정

    • 윗 내용은 타입이고 System.java 에서 out은 그대로 null
    • System.java에서 setOut() 가 아닌 SetOut0() 으로 newPrintStream 을 이용해 PrintStream 객체를 만들어주고 넘김 setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
    • 근데 정의 부분은 없고 이것 만 있음.. private static native void setOut0(PrintStream out);
    • 댓글 감사드립니다 :) System에서 out을 선언하지만, filterOutputStream 에서도 OutputStream out을 따로 생성해주고 있습니다. PrintStream 생성자에서 건드리는 out은 , filterOutputStream 에서 생성된 out이구요. System 에서 만들어준 out을 건드리는건 아닌것 같네요. 같이 고민해 주셔서 감사합니다 :) 심승현 2018.8.23 19:38
    • 저도 setOut에서 System.out을 정의한다고 보는데, 말씀하신 setOut0(~~) 이 부분에서 fdOut 에 관련하여 위에 FileOutputStream이라는 부분을 보아하니 표준출력인 콘솔을 File로 바꾸기 위해서 사용하는 부분같아보여요... 어렵네요 ㅠㅠ 심승현 2018.8.23 20:47
    • 안녕하세요 제 생각 정리해보겠습니다. setOut() 가 아닌 setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); 이부분인것 같습니다(뒤에 숫자0이 있습니다;) 정의부분은 private static native void setOut0(PrintStream out); 로 되어있는데 native 키워드 인거 보니 다른 언어로 정의되어있는 것 같아요 ㅠㅠ 최진우 2018.8.23 21:11
    • 이거 보고 native키워드가 다른언어라고 생각했어요. https://hashcode.co.kr/questions/613/자바에서-native키워드가-뭔가요 그리고 계속 찾아보니 http://hg.openjdk.java.net/jdk10/jdk10/jdk/file/9b8c96f96a0f/src/share/native/java/lang/System.c 여기에 372줄에 정의되어있네요 휴~ 최진우 2018.8.23 21:14
    • private static native void setOut0(PrintStream out); 여기서 native에 의해서 다른 언어로 out이 초기화 된다고 봐야 겠네요. 같이 고민해주셔서 감사합니다 :) 심승현 2018.8.23 21:38
    • !!!!!!!!!!!!!!!!! 정말 감사합니다! 이렇게 까지 뜯어봐주실 줄이야 너무나 감사합니다. 오늘도 많이 알고 가네요! 이런 내용은 어떻게 찾는건가요...? 조심스럽게 물어봅니다 알려주세요! 심승현 2018.8.23 21:58
    • setOut0 정의부분이 어디지? -> 없네..native? 머지? -> 해쉬코드검색 -> JNI 알게됨 -> 구글링(How to find jni code in java) -> 스택오버플로우에서 오픈jdk링크 찾음 -> url 수정해봤더니 됨 -> system.c 이렇게 찾았어요! 최진우 2018.8.23 22:12
    • 구웃..! 심승현 2018.8.23 23:35

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)