예지의 테크 로그포스 (Yeji's Tech Log Force)

System.out.println()으로 Java의 많은 것을 설명해보자! 본문

Java

System.out.println()으로 Java의 많은 것을 설명해보자!

Yeji Heo 2024. 1. 28. 20:44

오늘 글은 '챌린지'에 가깝다 ㅋㅋ!! 

 

지금까지 공부한 Java개념을 최~대한 접목시켜서

API를 열심히 뒤져가며 System.out.println()를 분석해보려고 한다.

 

매우 구구절절 꼬리에 꼬리를 묻는 글이라

분량 조절은 실패일듯 하지만..재밌는 글이 될 것 같다ㅎ.ㅎ

 

- Naming convention, CamelCase

- Dot Operator ( . )

- Has a / Is a

- Extends

- Access Modifier

- Overloading / Overriding

- println() 호출, toString()

- I/O

- Synchronized, write시 동기화 문제

- Exception

- 최상위 클래스 Object


 

1. Naming convention (CamelCase)

 

Java에서는 Naming convention중 CamelCase를 따른다.

CamelCase를 표기한 바와 같이 단어가 시작되는 부분을 대문자로 표기하는 컨벤션이다.

 

CamelCase는 UpperCamelCase, LowerCamelCase로 나눌 수 있다.

식별자의 시작을 대문자로 하느냐, 소문자로 하느냐의 차이이다.

주로 클래스명은 UpperCamel, 필드명은 LowerCamel을 쓴다. 메서드는 LowerCamel에 () 괄호 노테이션을 붙인다.

System.out.println();

 

System은 클래스구나,

out은 필드구나,

println()은 그 중 메서드구나.  

 

그리고 이들은 Dot Operator( . )를 통해서 System에서 out으로, out에서 println()으로 접근하고 있구나.

Dot Operator의 쉬운 이해: 

'나'에게 접근하려면? 우주.지구.아시아.대한민국.서울.나


2. Has - a 관계

 

System이 ( . )을 통해 out에 접근했다.

==> System이 out이란 필드를 가지고 있구나.

==> System (has - a) PrintStream out

 


 

3. Is - a 관계

 

out의 DataType은 PrintStream이구나. 

그런데 정작 PrintStream에는 out이란 필드가 보이지 않는다?!

PrintStream의 필드 부분. out은 없다.

 

out은 없지만 FilterOutputStream을 extends하고있다.

 

==> 그럼 out은 PrintStream보다 상위클래스인

FilterOutputStream(혹은 그보다 더 상위 클래스)에 있나보다.

 

 

도큐먼트에서 PrintStream의 Field요약을 보니 

 

==> out은 역시나 FilterOutputStream으로부터 온 것이었구나.

 

==> System.out에서 PrintStream타입인 out은 상속(extends, 확장)을 통해

상위 클래스(FilterOutputSteam)의 OutputStream타입인 out에 접근하는 것이구나.

FilterOutputStream클래스에서 OutputStream타입의 out을 확인

 


 

4. Access Modifier (protected)

 

out의 접근 제한자(Access Modifier)는 protected구나.

 

==> FilterOutputStream을 상속하거나

같은 패키지에 있는 클래스들만 out에 접근할 수 있겠다.

 


 

5. Static 키워드

 

인스턴스를 통해 필드에 접근하지 않고, System이란 클래스명으로 out 필드에 접근

 

==> out은 Static한 필드구나. 

인스턴스 간에 상태 값이 다르지 않아서,

그냥 Static영역에 올려놓고 공유해서 쓰는구나.

 

==> 그래서 인스턴스를 생성하지 않고,

클래스명으로 접근했구나!!


 

6. Overloading 오버로딩

 

out이라는 PrintStream타입의 필드는 ( . )을 통해서

println() 메서드에 접근했네?

 

==> PrintStream클래스에 println()이라는 메서드가 있나보다.

 

그런데 println()이라는 같은 이름의 메서드가

파라미터만 다르게하여 다양하게 쓰이고 있네?

 

==> 파라미터를 달리 함으로써 하나의 이름으로

메서드를 다양하게 활용할 수 있는 '오버로딩'을 하고 있구나

 


 

 

8. println()에서 toString()

 

println()에 인자로 레퍼런스만 넣어줘도,

다시 말해, toString()을 굳이 붙여주지 않아도 호출해서 출력이 되네?

 

==> println()이 내부적으로 toString()을 호출하기 때문.

 

자세한 내용은 전에 작성한 글을 참고해주세요!

 

Java에서 출력할 때 toString()을 생략해도 되는 이유

많은 사람들이 print(), println() 등 출력메서드를 사용할 때 toString()을 생략해도 된다! 라고 생각만 하거나 혹은 몰랐지만 그냥 그렇게 썼다거나 할 것이다. 도대체 왜 그런지 갑자기 궁금해서 패키

crayeji.tistory.com

 

 

9. Overriding 오버라이딩

 

println()의 인자로 레퍼런스를 넣을때, 

레퍼런스 타입마다 출력 양식이 다르다. 

 

가령, Vector<Integer>는 [1, 2, 3, 4] 이런식으로 대괄호에 묶여 출력되고

String은 문자열로 쭉 나온다.

 

==> toString()의 메서드 시그니처를 유지하면서

구현부는 서로 다르게 하였구나

 

==> toString()을 오버라이딩 했구나.

 

Long클래스가 오버라이딩한 toString() 예시

 

 


 

 

10. 최상위 클래스인 Object

 

오버라이딩은 상속 관계에서 슈퍼클래스의 메서드를 수정/확장하는 개념이다.

대부분의 클래스들이 toString()을 오버라이딩하고 있다는데,

 

정작 String, Long등 클래스를 직접 확인해보면

extends 키워드를 사용해서 뭔가를 상속한 흔적이 보이지 않는다.

 

extends도 하지 않았는데 도대체 어떤 toString()을 오버라이딩 한다는 거야?

 

==> 모든 클래스는 Object라는 최상위 클래스를 상속하며,

이는 클래스 선언부 뒤에서 생략된 것이다(extends Object)

 

==> Object의 toString()을 오버라이딩해서 사용하고있다.

 

 

자세한 내용은 전에 작성한 글을 참고해주세요!

 

Java 모든 Class는 Object Class를 상속 받는다(feat. 오버라이딩)

Java를 공부해 본 사람이라면 다들 이런 말은 들어보셨을 것이다. Object는 모든 Class들의 최상위 클래스다. OOP를 공부하면서 Object 클래스를 제대로 살펴보지 않을 수는 없지!!! 우선 위의 말이 진짜

crayeji.tistory.com

 

 


 

 

10. Synchronized

한편, print()는 write()를 호출하길래

write()를 살펴보니 synchrosized라는 키워드가 붙어있다.

 

만약 우리가 파일에 write를 하고 있는데,

다른 사람이 내 파일(리소스)에 동시에 접근해서 write를 해버리면

동기화 문제가 발생해서 신뢰성이 떨어진다.

 

==> write할 때 Synchronized 키워드를 붙여서 다른 Thread의 동시 접근을 막았구나.

 

==> Synchronized block을 사용해서 동기화 범위를 조절할 수 있구나

(특정 범위 외에는 굳이 lock하지 않아도 될 때 효율적이겠다)

 


 

11. try ,catch 예외처리

 

write()는 try - catch를 통해 예외도 처리하고 있구나.

 

 ==> 혹시라도 Interrupted라는 예외가 발생하면

currentThread()를 interrupt()하는구나.


 

+ 오늘의 여담

System.out.println()

처음 Java파일을 생성하기만 해도 마주칠 수 있는 익숙한 코드이다.

 

이를 단순히 '출력'정도로만 덮어두고

돌아간다 신난다~ 하면

속에 숨은 수 많은 원리와 개념을 알기는 힘들 것이다.

 

관심을 가지지 않는 개발자가 되고 싶지는 않으니까

결론: 공부할 수 있을 때 계속 공부하자 ^____^ ! !

Comments