[프로그래밍] AWT, Deprecated, Concrete, process, 입출력 Stream, 절차 은닉
<<<AWT>>>
java.awt 패키지는 자바에서 지원하는 Graphic user interface 클래스들이다. 그러나 자바는 C에 비해 느리기 때문에 사용자 용이 아니라 서버 용이고, windows gui에 비해 뒤떨어지기 때문에 현업에서 잘 사용하지 않는다. 계열 최상위 클래스는 Component 클래스이다. 추상메서드 없이 클래스가 abstract로 선언된 걸 보니 공유 목적으로 만든 클래스임을 알 수 있다.
<<<Deprecated>>>
java.util.Calandar를 보면 인스턴스 생성을 못하도록 abstract 선언을 해 두었다. 특정 시간으로 인스턴스를 생성하면 시간이 지났을 때 과거가 되기 때문이다. 그러나 calandar는 현재 시간을 확인하기 위한 목적이므로 알맞지 않게 된다. 그러나 Date 클래스를 보면 인스턴스 생성이 가능하다. API에서 Date의 생성자를 보면 Deprecated 라고 되어 있는데, JDK 1.1 이후에는 Date보다 Calandar를 쓰는 것을 추천한다. 이렇게 지원되지만 사용을 권장하지 않는 API를 Deprecated API라 한다. 마찬가지로 메서드 목록을 보면 All, static, instance, concrete, deprecated로 나누어 볼 수 있는데 deprecated 메서드는 사용을 권장하지 않는 메서드이다.
<<<Concrete>>>
concrete class 는 interface class를 implement한 클래스를 의미한다.
concrete는 클래스 API의 메서드 목록에서도 확인할 수 있는데, 이는 명확히 정의된 method라는 뜻이다. 상위클래스의 메서드를 overriding 했다면 다시 정의되었다는 의미의 concrete이고, overriding되지 않았다면 method body가 있기 때문에 abstract가 아니라는 뜻도 된다. 또한 final로 선언되지 않았다면 상속받은 클래스에서 overriding이 가능하다.
<<<process>>>
OS에서 어플리케이션을 돌리는 걸 말한다.
<<<유니코드 Unicode>>>
유니코드(Unicode)는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이다.유니코드의 목적은 현존하는 문자 인코딩 방법들을 모두 유니코드로 교체하려는 것이다. 기존의 인코딩들은 그 규모나 범위 면에서 한정되어 있고, 다국어 환경에서는 서로 호환되지 않는 문제점이 있었다. 유니코드가 다양한 문자 집합들을 통합하는 데 성공하면서 유니코드는 컴퓨터 소프트웨어의 국제화와 지역화에 널리 사용되게 되었으며, 비교적 최근의 기술인 XML, 자바, 그리고 최신 운영 체제 등에서도 지원하고 있다.
<<<입출력 스트림>>>
java.lang 패키지는 자바를 사용하는 데에 기본적인 Bean들을 모아두었고, java.util 패키지는 유틸리티성 Bean들을 모아두었다. java.io 패키지는 JVM에서 실행시킬 때(process) 외부에서 데이터를 .class에게 입력하고 .class에서 외부로 데이터를 출력해주는 기능을 추상화 캡슐화 하여 모델링한 Bean이다. 즉 InputStream은 표준입력장치(System에선 키보드)를 추상화 한 class이고, OutputStream은 표준출력장치(System에선 모니터)를 추상화 한 class이다. (System이 컴퓨터를 추상화 한 클래스임을 알 수 있다.)
스캐너를 사용할 때에 스캐너 생성자에 System.in을 전달했었다. System.in의 데이터타입은 InputStream이다. InputStream class는 System에서 들어오는 입력을 모델링했다. 반대로 출력은 OutputStream이다. InputStream과 OutputStream은 계열최상위이다. InputStream은 abstract 클래스로 read()라는 추상메서드가 있다. InputStream을 상속받은 클래스들에는 모두 read()라는 메서드가 있음을 알 수 있다. OutputStream은 writer() abstract 메서드가 있으니 OutputStream을 상속받은 클래스는 writer 메서드가 오버라이딩 되어있음을 알 수 있다.
자바는 명시적인 것을 추구하는 언어이기 때문에 읽어들이는 것과 출력하는 것을 동시에 하지 않고 읽고 쓰는 것을 다르게 모델링 해 놓았는데 이를 단방향 Modeling이라고 한다.
InputStream과 OutputStream은 1byte씩 읽어들이고 내보낸다. 이를 binary 형식이라하고 이들을 묶어 바이트스트림이라 한다. abc를 한번에 입력했다 하더라도 a, b, c의 순서대로 읽어들인다. 먼저 입력받은 것을 먼저 출력해주는 FIFO 구조, Queue 구조임을 확인할 수 있다. 또한 1byte씩 읽어들이기 때문에 read가 실행된 횟수가 읽어들인 것의 크기byte가 된다. 영어권에서는 아스키코드로 하나의 문자를 숫자로 파악하기 때문에 InputStream의 read는 return type이 int이다. 그리고 출력할 때에 system.out.println();으로 출력한다면 int로 입력받은 것을 char로 명시적 형변환 해야 했었는데, OutputStream의 write() abstract method argument가 int인 것으로 보아 read()를 통해 출력된 값을 write()에 넣어도 char로 형변환하여 출력해 줌을 알 수 있다.
여기서 스트림은 byte의 연속을 의미한다. InputStream과 OutputStream의 하위 클래스에서 read() 혹은 write()해서 처리하는 byte들이다. (sequences연속 of bytes라고 한다)
1byte씩 데이터를 처리하면 영어가 아닌 문화권의 문자가 입력되었을 때 깨져서 나온다. 바이트가 아닌 하나의 문자 단위로 입출력을 지원하는 Bean을 지원해주는데 그것이 Reader와 Writer abstract class이다. 여기에는 InputStream OutputStream과 같이 abstract read()와 abstract write()가 각각 포함되어 있으며 return type, 매개변수도 int로 같아 입출력에서 일관성을 유지한다. Read와 Writer는 문자 단위로 입출력을 지원하기 때문에 이들을 묶어 문자스트림 이라고도 한다. Read의 read()가 실행된 횟수는 읽어들인 것에 몇 개의 문자가 있는지를 확인할 수 있다.
InputStream을 상속받은 많은 클래스들은 다양한 입출력을 처리해준다. 그러나 Reader와 Writer는 클래스가 InputStream과 OutputStream에 비해 많지 않다. 그러나 Reader와 Writer로 사용하지 못하는 것이 아니다. 바이트스트림을 문자스트림으로 이용할 수 있는데 다형성을 구현한 인터페이스 기반 프로그래밍 개념을 활용하면 된다. 이를 지원하기 위해 자바진영에서 InputStreamReader와 OutputStreamWriter 클래스를 만들었다. InputStreamReader클래스는 Reader클래스를 상속받은 클래스로서 인스턴스 생성 시 Reader 데이터 타입으로 선언될 수 있다. 또한 InputStreamReader의 생성자를 보면 생성자가 받는 데이터타입이 InputStream이다. 이는 InputStream의 하위 클래스들을 인스턴스로 Reader 클래스로 사용할 수 있음을 지원하는 것으로, 개념적으로 말하면 바이트 스트림을 문자 스트림으로 활용할 수 있도록 하는 것이다.
자바에서는 입출력 스트림시 지연(block)이 발생할 수 있다. block은 process가 진행되지 않고 기다리는 것이다.
<<<System.in>>>
System.in은 InputStream 형태로 지정되어 있다. System 클래스는 자바 버추얼 머신을 구성하고 있는 표준 장치를 뜻하는 클래스이다. 자바 버추얼 머신은 그 자체가 완벽한 하나의 컴퓨터 플랫폼을 가정하고 있기 때문에 독립적으로 동작할 수 있는 구조를 표현하기 위하여 표준 입력과 표준 출력을 스스로의 System 클래스에 등록하여 사용한다.
여기에서 주목해야 할 부분은 System.in 변수의 타입이 InputStream 이라는 점이다. InputStream 클래스는 최상위 클래스이면서 추상 클래스이다. 따라서 InputStream은 객체를 생성할 수 없는 클래스이다.
그런데도 System.in은 실제로 객체가 존재하고 있으며 이를 통하여 키보드 입력을 받을 수 있다. 이것은 변수의 타입은 선조 클래스이지만 실제 객체는 후손 객체이다. 자연스러운 형 변환이 지원되기 때문에 가능하다.
System.in을 통하여 접근되는 객체는 자바 버추얼 머신이 메모리로 올라오면서 미리 객체를 생성해 놓는, 대표적인 객체이다.
(출처: https://hyeonstorage.tistory.com/235 [개발이 하고 싶어요])
<<enter엔터 = \n \r>>
입출력 시 외부에서 키보드를 이용해 세 글자 "홍길동"을 입력하고 enter엔터를 누른다면 입력받은 문자는 5개가 된다. 엔터를 누르는 것이 시스템 내부적으로 "\n"과 "\r"를 입력받은 것으로 처리되기 때문이다. 타자기를 생각해보면 한 줄을 다 입력했을 때 다음 줄로 넘기고 다시 처음부터 글자를 입력할 수 있도록 오른쪽으로 종이 자리를 옮긴다. 여기서도 \n은 계행, \r은 carrage return 즉 첫 글자 타이핑이 시작되는 곳으로 옮기기 작업이다. 문자를 제대로 입력받으려면 이 처리도 해줘야 한다.
<<<IO Buffer, flush()>>>
정식으로 JVM 밖에서 "문자를" 입력받고 출력하기 위해서는 다음과 같은 과정이 필요하다. 먼저 InputStreamReader 인스턴스를 만들어 입력된 내용을
io buffer에 출력할 문자들을 저장해두고 flush라는 명령이 떨어졌을 때 한 번에 출력한다.
<<<입출력 스트림 close(), null check>>>
close()메서드는 flush()메서드를 호출해 IO Buffer 메모리에 있는 write()된 것들을 출력하고 입출력 자원을 반납한다.
입출력 스트림은 .class 내부의 자원이 아닌 외부에서 입력받고 외부로 출력하는 장치를 빌려온 것이다. 따라서 사용이 끝났을 때 close()메서드를 이용해 반납해야 한다. 예외상황의 발생여부와 관계 없이 close()메서드를 이용해 닫아줘야 하기 때문에 try catch로 예외 상황을 찾아내고 finally에 close()를 담는다. close() 메서드를 활용할 때에는 Reader나 Writer가 열려있는지 확인해야 한다. IOException이 발생했다면 Reader나 Writer 인스턴스가 생성되지 않았을 수 있다. 그렇다면 없는 인스턴스를 닫는 것이기 때문에 null point exception이 발생한다. 따라서 finally에서 close를 사용할 때에는 반드시 null check를 해줘야 한다. finally{try{if( 변수명 != null){변수명.close()}}catch(Exception e){e.printStackTrace();}
<<<상대경로, 절대경로>>>
절대경로란 root폴더에서 시작해 목적지까지 접근하는 주소이다. 내가 지금 어느 디렉토리에 있던 변하지 않는 경로이다.
상대경로란 현재폴더에서 시작해 목적지까지 접근하는 주소이다.
<<<인터페이스 클래스는 static final로 필드를 가질 수 있다>>>
<<<class는 access modifier로 protected와 private를 가질 수 없다>>>
<<<절차 은닉>>>
Encapsulation을 구현하는 방법에는 정보를 숨기는 information hiding 정보 은닉과 메서드의 진행 내용을 숨기는 절차 은닉이 있다.
절차은닉은 인터페이스 기반 프로그래밍으로 구현할 수 있는데, 협업자가 만드는 메서드 내부에서 구체적으로 어떤 클래스 데이터 타입을 사용하든지에 관계 없이 return type을 계열 상위 인터페이스 데이터타입으로 설정한다면 return 값을 받아 처리할 때 유연하게 코딩할 수 있다.
<<<Query쿼리문 = SQL문>>>