Power Java compact 정리

2019. 7. 9. 14:41Engineer

반응형

안드로이드 앱프로그래밍 공부의 기초는 다진 듯하다. 책1권과 동영상 강의 2개를 보았더니 내용적인 면에서는 크게 차이가 없다는 것을 느꼈다. 이제 Java에 대해서 다시 공부를 더 해봐야겠다고 생각이 들어서 Java 기초 책을 하나 빌렸다. 제목은 Power Java (천인국 저) 이다. 


Java에 대해서도 이전에 동영상 강의로 기초 공부를 해서 그런지, 책이 쉽게 읽혀졌고 3일정도 보니 마지막장을 넘길 수 있었다(실습 문제 하나도 안하고.....). 뭐랄까 현재의 나는 연애를 책으로 배운 연애 중수 라고나 할까? 이제 만들고 싶은 앱을 만들면서 필요한 공부를 해도 될 것 같다는 생각이 든다. 얼마전에 읽은 '벤처타는 프로그래머' 책에서도 아래와 같은 글이 나를 자극하고 있으니.

'완벽'해야만 비로소 일을 착수할 수 있는 사람들의 딜레마는 '어느 정도가 완벽한 준비인가?'에 대한 기준이 모호하다는 것이다. 실패를 줄이기 위한 준비가 되었느냐에 못지않게 중요한 것이, 비록 준비가 덜 되어 있더라도 그것을 실행에 옮길 수 있느냐의 여부다. 이때 필요한 것이 '도전 정신'인데 이 도전 정신은 예상치 못한 실패에 대한 걱정보다는 그 과정에서 무엇을 얻을 수 있을 것인가가 더 중요한 사람들만이 가질 수 있다


그리고 JAVA 관련 책으로 많은 블로그나 전문가들이 effective JAVA 책을 많이 추천하는 것을 보았다. 그래서 다음으로 볼 책은 effective JAVA 최신판으로 빌리거나 혹은 구입해서 볼 예정.


책 내용 중 기억하고싶은 내용 정리


   Chapter 01 자바 소개

1991년 제임스 고슬링이 개발. 가정용 전자 제품에 사용할 수 있는 작고 간결하며 네트워크 기능을 내장한 컴퓨터 언어로 설계. 자바는 Java Virtual Machine에 의해서 실행되므로 플랫폼에 종속되지 않음. 대신 해당 플랫폼에 JVM이 설치되어 있어야 함. 

  • JRE(Java Runtime Environment) : 자바 프로그램을 실행하기 위한 라이브러리, JVM, 기타 컴포턴트들을 포함 
  • JDK(JAVA Development Kit) : JRE에 포함된 내용에 추가적으로 자바 프로그램을 개발하는데 필요한 컴파일러, 디버거와 같은 도구들을 포함

JDK 8은 2014년에 출시

JDK 9은 2017년에 출시

자바 API 문서는 https://docs.oracle.com/en/java/javase/12/  (현재 JDK 12)


자바로 만들수 있는 것

  • 자바 애플리케이션(Java application) : 독립적으로 실행될 수 있는 일반 응용 프로그램. 
  • 자바 애플릿(Java applet) : 단독으로 실행되지 않고 웹 브라우저 안에서 실행되는 작은 자바 프로그램
  • 자버 서블릿(Java servlet) : 웹서버에서 동작하는 서버 모듈. 클라이언트의 요구를 받아 처리한 후 실행 결과를 HTML 형태로 응답
  • JSP (Java Server Page) : HTML안에 자바 코드를 넣어 웹페이지를 사용자와 상호작용하도록 만든 것
  • 안드로이드 애플리케이션 : 안드로이드를 위해 자체적으로 개발한 가상 머신에서 동작하는 애플리케이션. 자바의 SE버전 중에서 AWT와 스윔(swing)을 제외한 거의 모든 패키지 사용가능. 


   Chapter 02 자바 프로그래밍 기초

클래스(class) : 자바 프로그램의 빌딩 블록. 클래스가 모여서 자바 프로그램이 됨. 소스 파일 이름은 내부에 public이 붙은 클래스의 이름과 동일해야함. 하나의 소스 파일안에 public 클래스가 2개 이상이면 컴파일 오류 발생 

메소드(method) : 어떤 특정한 기능을 수행하는 코드들의 집합. 클래스 안에 선언된 함수. 

패키지(Package) : 클래스들을 모아 놓은 곳


자료형

  • 기초(기본) 자료형 : 실제 값을 저장 (ex. byte, int, short, char, double. ...)
  • 참조형 : 실제 객체를 가리키는 주소 저장 (ex. string, ....)


long 으로도 안되는 큰 정수는 BigInteger 클래스 사용

부동소수점형은 정확성이 필수인 금융 계산에 적합하지 않다. 예를 들어 0.1은 이진법으로 정확히 표현할수 없기 때문이다. 부동소수점형은 이진법에 기초를 두고 있다. 따라서 정확한 수를 계산하려면 java.math.BigDecimal 클래스를 사용해야 함 


유니코드 방식에는 UCS-2, UCS-4, UTF-4,  UTF-7,  UTF-8,  UTF-16 인코딩 등의 다양한 인코딩 방식이 있음. 이중 UTF-8이 가장 많이 사용되고 있음. 하지만 현재 java 의 string 객체 내부에서는 UTF-16인코딩으로 문자열을 저장. (지금도 그런지 확인 필요


   Chapter 03 선택과 반복

자바에서 배열은 객체. 배열은 한번 생성되면 크기를 변경할 수 없음. 만약 실행중 배열의 크기를 변경하여야 한다면 ArrayList나 Vector 클래스를 사용해야 함

for-each 루프 : 배열의 각 요소를 순차적으로 접근 할 수 있음. 배열의 크기에 신경 쓰지 않아도 되고, 인덱스 값을 저장하는 변수를 생성할 필요 없음. 하지만 배열 요소의 값을 변경하거나 역순으로 배열 요소를 처리하는 경우, 전체가 아니고 일부 요소만 처리하는 경우, 하나의 반복 루프에서 두개 이상의 배열을 처리하는 경우에는 for-each 루프는 부적합. 이때는 for 루프를 사용. 


ArrayLIst : 배열의 크기를 자동으로 변경하면서 사용 할 수있음.  


   Chapter 04 클래스, 객체, 메소드

객체(Object)는 객체 지향 기술의 핵심 개념. 객체는 상태(state = 변수or필드)와 동작(behavior = 함수or메소드)을 가지고 있다. 


객체에 대한 설계도를 클래스(class)라 한다. 클래스란 특정한 종류의 객체들을 찍어내는 형틀 또는 청사진이라 할 수 있다. 클래스로부터 만들어지는 각각의 객체를 그 클래스의 인스턴스(instance)라고 한다. 클래스 안에는 필드와 메소드들을 정의한다. 이들은 클래스의 멤버(member)라고 불린다. 필드는 객체의 상태를 나타내고 메소드는 객체의 동작을 나타낸다. 


public은 외부에서 클래스를 자유롭게 사용할 수있다는 접근 지정자이다. 


객체의 필드나 메소드에 접근할 때는 점(.) 연산자를 사용한다


메소드는 클래스 안에 정의된 함수이다. 각 메소드는 이름을 가지고 있으며 메소드를 호출할 때 이름을 사용한다. 메소드를 호출시 전달하는 값을 인수(argument)라하고 메소드에서 값을 받았을 때 사용하는 변수를 매개변수(parameter)라 한다. 


자바에서는 같은 이름의 메소드가 여러개 존재할 수 있다. 이것을 메소드 중복 정의(method overloading)라 한다. 중복 정의를 위해서는 반드시 메소드의 매개변수가 달라야한다. 


생성자(constructor)는 객체가 생성될 때 객체를 초기화하는 특수한 메소드이다. 생성자의 이름은 클래스 이름과 같다. 일반 메소드와 흡사하지만 반환값을 가지지 않는다. 그중에서도 매개변수가 없는 생성자를 기본 생성자(default constructor)라 한다. 개발자가 생성자를 정의하지 않으면 자바 컴파일러는 기본 생성자를 자동으로 만들며 수치형 변수는 0으로, 참조형 변수라면 null로, 부울형 변수라면 false로 초기화한다.  


this 참조 변수는 현재 객체를 가리키는 참주 변수이다. 흔히 생성자에서 매개 변수 이름과 필드 이름을 구별하기 위해 사용한다.this에 ( )를 붙이면 전혀 다른 의미가 된다. this( )는 다른 생성자를 의미한다. 


접근 제어(access control)란 클래스의 멤버에 접근하는 것을 제어하는 것으로, public이나 private의 접근 지정자를 멤버 앞에 붙여서 접근을 제한한다. 


접근자(getters)와 설정자(setters)를 쉽게 판단하는 방법은 대게 get이나 set이 메소드 이름 앞에 붙여진다. 


자바에서 객체를 생성하는 유일한 방법은 new 를 사용하는 것이지만, 문자열(string)은 프로그램에서 아주 많이 사용되기 때문에 new를 사용하지 않고, 직접 값을 입력하는 방법으로 생성할 수 있다. (ex. String s1 = "java"; ). 하지만 이런 방식으로 생성할 경우 히프 메모리의 문자열 상수 풀에 동일한 값이 있을 경우, 이것을 참조하여 반환하게됨.  


   Chapter 05 클래스와 객체

여러개의 객체가 하나의 변수를 공유해야 되는 경우가 있는데 이러한 멤버를 정적 멤버(static member) 또는 클래스 멤버(class member)라 한다. 필드를 정의 할때 앞에 static을 붙이면 정적 멤버가 된다. 


인스턴스 멤버 vs 정적 멤버

동일한 클래스를 이용하여 많은 객체들이 생성될 때 각각의 객체(인스턴스)들은 자신만의 필드를 가진다. 이들 필드는 인스턴스마다 별도로 생성되기 때문에 인스턴스 변수(instance variable)라고 한다. 정적 변수(class variable)는 클래스 당 하나만 생성되는 변수이다. 하나의 클래스에 하나만 만들어지고 동일한 클래스의 모든 객체들은 하나의 정적 변수를 공유한다. 정적 변수는 객체 없이도 사용이 가능하다. 단순히 클래스 이름 뒤에 점 연산자(.)를 붙이면 사용가능하다.  


자바에서는 전역 변수(global variable)의 개념이 없다. 대진 정적 변수를 적절히 사용하면 전역변수와 같은 기능을 할 수 있다. 

변수와 마찬가지로 메소드도 정적 메소드로 만들 수 있다. 


자바에서 메소드의 매개 변수로 인수를 전달 시에 기초형 값이 전달 되는 경우 "값에 의한 호출"방식으로 전달 되어 인수의 복사본이 만들어지고 매게변수를 변경하여도 메소드 외부에 있는 인수에 영향을 주지 않는다. 반면 객체가 전달 되는 경우, 참조값(주소)이 매개변수로 복사되면 매개 변수도 동일한 객체를 참조하게 되고 이 매개변수를 이용하여 객체의 내용을 변경하면 인수가 가리키는 객체도 변경된다. 


자바에서는 클래스 안에서 클래스를 정의할 수 있다. 내부에 클래스를 가지고 있는 클래스를 외부 클래스(outer class)라 하고 내부에 포함되는 클래스를 내장 클래스(nested class)라 한다. 내부 클래스는 외부 클래스의 필드와 메서드를 전부 상요할 수 있다. private로 선언되어있어도 접근 가능하다.


   Chapter 06 상속

자바에서 상속은 extends 키워드를 이용. 기존에 존재하는 클래스로 부터 데이터와 코드를 이어받고, 필요한 기능을 추가할 수 있다. 하지만 부모 클래스의 private 멤버는 상속되지 않는다.


생성자의 호출 순서는 [부모 클래스 생성자] -> [자식 클래스의 생성자] 순으로 된다. 

자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자를 호출 할 수 있다. 이 때 super 라는 키워드가 사용된다. 이것을 명시적 호출 이라 한다. 

묵시적 호출은 super 클래스의 생성자를 호출해 주지 않아도 서브 클래스의 객체가 생성될때 자동적으로 super 클래서의 매개 변수가 호출된다. 이를 묵시적인 호출이라 한다. 묵시적인 부모 클래스 생성자 호출을 사용하려면 부모 클래스에 기본 생성자가 반드시 정의되어있어야 한다. 기본 생성자가 정의되어 있지 않으면 오류가 발생


자식 클래스는 부모 클래스의 메소드를 다시 정의할 수 잇다. 이것을 메소드 재정의(method overriding)라 한다. 이때 메소드의 이름이나 매개변수, 반환형은 동일하여야 한다. 


추상 클래스 : 완전하게 구현되어 있지 않은 메소드를 가지고 있는 클래스. 객체를 생성할 수 없다. 추상 클래스를 만들기 위해서는 클래스 선언시에 앞에 abstract를 붙인다. 하나 이상의 추상 메소드를 가지고 있어야 한다. 추상 메소드는 몸체가 없는 메소드를 말하며 항상 세미 콜론(;)으로 종료되어야 한다. 추상 메소드로 정의하면 서브 클래스에서는 반드시 구현하여야 하므로 구현을 강요하는 면에서 장점이 있다.


부모 클래스 참조 변수로 자식 클래스 객체를 참조할 수 있다. 이것을 상향 형 번환이라고 한다. 하지만 자식 클래스에서 추가한 메소드에 대하서는 부모 클래스의 참조변수로는 접근할 수 없다. 


어떤 참조 변수가 가리키는 객체의 실제 타입을 알고 싶으면 instanceof 연산사를 사용한다.


인터페이스(interface)를 정의 하는 것은 클래스를 정의하는 것과 유사하지만 키워드를 class 대신 interface를 사용한다. 인터페이스 안의 모든 메소드는 public과 abstract를 붙이지 않아도 public과 abstract로 취급된다. 

인터페이스만드로느 객체를 생성할 수 없다. 다른 클래스에 의하여 구현 될 수 있다. 클래스가 인터페이스를 구현하기 위해서는 implement 키워드를 사용한다. 상속과 동시에 인터페이스를 구현할 수있다. 


자바에서는 복잡한 문제를 피하기 위해 다중 상속을 금지하고 있다. 대신에 인터페이스를 이용하면 다중 상속의 효과를 낼 수 있다. 


   Chapter 07 패키지와 예외처리

자바는 서로 관련된 클래스들을 하나로 묶을 수 있는 방법을 제공하는데, 그것은 패키지(package) 이다. 표준 자바 라이브러리는 패키지들로 구성되어 있다. 


패키지를 생성하기 위해서는 소스코드의 첫번째 줄에 package문을 넣으면 된다. 패키지안에 들어있는 클래스나 인터페이스를 사용하기 위해서는 두가지 방법이 있다.

  • 클래스 이름에 패키지를 붙여서 참조하기
  • 패키지를 소스코드에 포한하기 (import 사용)  

Object 클래스는 finalize( )라는 콜백(callback) 메소드를 정의한다. 이것은 객체가 소멸되기 직전에 호출된다. 서브 클래스에서 재정의하여 자원을 반납하는 등의 정리 과정을 실행 할 수 있다. 


자바에서는 정수나 실수와 같은 기초 자료형을 제외하고는 모든 것이 객체로 되어있다. ArrayList에 기초 자료형을 넣으려면 기초 자료형을 객체로 포장해여야 한다. 이러한 작업을 해주는 것이 Wrapper 클래스이다. Wrapper 클래스는 정수와 같은 기초 자료형을 저장하고 있는 클래스이다. 자바의 각 기초 자료형에 대하여 해당하는 Wrapper 클래스가 존재한다.


자바에서 예외처리를 하는 방법은 두가 지가 있다.

  • try-catch 블록을 사용하여 예외를 처리하는 방법
  • throws를 사용하여 다른 메소드한테 예외 처리를 맡기는 방법 

try-with-resources 는 try-catch 블록 내에서 사용되는 리소스들을 자동으로 닫는 기능이 있다. 


   Chapter 08 자바 GUI 기초

GUI는 컴포넌트(component)로 이루어진다. 컴포넌트랑 버튼이나 체크박스와 같은 기본적인 빌딩 블록을 의미한다. 자바에서 사용할 수 있는 GUI에는 AWT(Abstract Windows Toolkit)와 스윈(Swing)이 있다. AWT는 초기 자바 버전에서 제공하였던 GU이다. 스윙은 AWT와 달리, 컴포넌트가 자바로 작성 되어 있기 때문에 어떤 플랫폼에서도 일관된 하면을 보여준다. 


자바가 제공하는 컴포넌트는 크게 컴포넌트와 컨테이너로 나누어 진다. 


자바 스윙에서 JFrame 객체를 만들면 윈도우를 담당하는 새로운 스레드가 하나 생성된다. 따라서 main()이 종료되더라도 윈도우는 없어지지 않는다.


컨테이너는 컴포넌트들을 트리 형태로 저장한다. 최상위 컨테이너는 이 트리의 루트가 된다. 각 컴포넌트들은 한번만 컨터이너에 포함될 수 있다. 최성위 컨테이너는 메뉴바를 추가할 수 있다. 


배치 관리자는 컨테이너 안에 존재하는 컴포넌트들의 크기와 위치를 자동적으로 관리하는 객체이다. 대표적으로 BorderLayout, FlowLayout, GridLayout 등이 있다. 배치 관리자 없이 절대 위치로 컴포넌트를 배치할 수도 있다. 


패널(panel)은 컴포넌트들을 포함하고 있도록 설계된 컨테이너의 일종이다. 별도의 패널을 쓰는 것이 유지 보수 및 배치 관리에 편하다. 


   Chapter 09 이벤트 처리

객체 지향 프로그램에서 모든 작업은 객체가 한다. 이벤트 처리도 객체가 한다. 이벤트를 처리하는 클래스를 정의하고 이 클래스의 객체 A를 생성한다. 이벤트가 발생하는 객체 B에 A 객체를 등록하면 차후에 이벤트 발생시 객체 A가 이벤트를 처리한다. 이것을 위임(delegation)이라 한다. 


이벤트 처리 

  1. 이벤트를 처리할 클래스 정의 : 리스너 인터페이스는 어떤 클래스가 이벤트를 처리하기 위해 구현해야 하는 규격이다. 
  2. 컴포넌트에 이벤트 처리 객체 등록 : 컴포넌트에 리스너 객체를 등록해야만 이벤트가 발생시 처리할 수 있다. 
이벤트 객체는 발생된 이벤트에 대한 모든 정보를 리스너로 전달한다. 이벤트 객체의 getSource( )는 이벤트를 발생한 컴포넌트를 반환한다. getSource( )는 Object 타입으로 반환하므로 이것을 필요한 자료형으로 형변환하여 사용하면된다. 

여러가지 이벤트 처리 방법
  • 프레임 클래스가 이벤트 처리 : 프레임 클래스가 JFrame 을 상속받으면서 동시에 리스너 인터페이스도 구현하는 방법
  • 무명 클래스를 사용하는 방법 : 안드로이드 프로그래밍에서 자주 사용되는 방법이다. 이름 없는 클래스를 작성하여, 한번만 사용하는 것이다. 

람다식(lambda expression)은 이름 없는 메소드(함수)라 할 수 있다. 람다식을 이용하면 메소드가 필요한 곳에 간단히 메소드를 보낼 수 있다. 람다식은 메소드를 객체로 만드는 것이다. 


이벤트 리스너를 작성할 때 주의할 점은 이벤트를 빠른 시간 안에 처리해야 한다는 점이다. 모든 그리기와 이벤트 처리가 동일한 스레드 안에서 실행되므로 이벤트 처리가 늦어지면 프로그램이 마우스나 키보드에 반응하지 않게 된다. 만약 이벤트 처리가 길어질 것 같으면 별도의 스레드를 생성하여 그 스레드가 작업하도록 해야 한다. 


키보드 이벤트를 처리하려면 KeyListener 인터페이스를 구현해야 한다.  KeyEvent가 발생하려면 컴포넌트가 반드시 키보드 포커스를 가지고 있어야 한다. 키보드 포커스를 얻으려면 requestFocus( ), setFocusable(true)를 호출해야 한다. 


마우스 버튼 이벤트를 처리하려면 MouseListener를 구현해야 한다. 마우스가 이동할 때 마우스의 위치를 받으려면 MouseMotionListener 를 구현해야 한다. 


이벤트를 처리하기 위해 리스너 인터페이스에 정의되어있는 모든 메소드를 구현해야 하지만 이러한 문제를 해결하기 위해 어댑터 클래스(Adaptor Class)가 있다. 어댑터 클래스는 인터페이스를 구현해 놓은 클래스이다. 어댑터 클래스를 상속 받아서 원하는 메소드만 재정의 하면 된다.  


   Chapter 10 스윙 컴포넌트

자바에서 GUI프로그램을 작성하려면 스윔에서 제공하는 컴포넌트를 사용해야 한다. JComponent는 거의 모든 스윙 컴포넌트의 부모 클래스이다. 


   Chapter 11 자바 그래픽

자바는 java.awt.Graphic 클래스를 통하여 그래픽 기능을 제공한다. Graphics 클래스는 세가지 유형의 메소드를 제공한다. 

  • 텍스트 문자열 : drawString( ) 메소드를 통해 텍스트를 화면에 그릴 수 있다. 
  • 기초 도형들: drawXXX( ), fillXXX( ) 형식의 메소드들을 통하여 직선, 사각형, 타원 등을 화면에 그릴 수 있다.
  • 이미지 : drawImage( )메소드를 통해 화면에 이미지를 그릴 수 있다.

프레임 위에 그림을 그리는 것보다 다른 컴포넌트 위에 그린 후에 그 컴포넌트를 프레임에 추가하는 것이 좋다. 일반적으로 JPanel에 그림을 그릴기 좋다. JPanel을 상속받은 자식 클래스를 작성한후 이것을 그림 그리는 캔버스로 사용하자 .


각 컴포넌트는 자신을 그리는 코드를 가지고 있다 컴포넌트의 paintComponent( ) 메소드 인데 이것을 재정의하고 여기에 우리가 그리고자 하는 코드를 추가하면된다. paintComponent( ) 메소드는 컴포넌트를 다시 그릴 필요가 있을 때마다 자바 시스템에 의해 호출되는 메소드이다. 만약 그림이 그려지는 컴포넌트가 그래픽 컴포넌트인 경우, super.paintCompoenet( )를 호출해주는 것이 좋다. 부모 클래스가 그려야 할 부분도 있기 때문이다. 자기 그림만 그리고 종료해 버리면 부모 클래스는 그릴 기회를 얻지 못한다.


   Chapter 12 제네릭과 컬렉션

제네릭 프로그래밍이란 다양한 종류의 데이터를 처리할 수 있는 클래스를 작성하는 기법이다. 안드로이드와 같은 애플리케이션을 개발할때 많이 사용된다. 제네릭은 클래스를 정의할 때, 클래스 안에서 사용되는 자료형(타입)을 구체적으로 명시하지 않고 T와 같이 기호로 적어놓는 것이다. 객체를 생성할 때, T 자리에 구체적인 자료형을 적어주면된다. 


자바 7버전 부터는 제네릭 클래스의 생성자를 호출할 때, 타입 인수를 구체적으로 주지 않아도 된다. 컴파일러는 문맥에서 타입을 추측한다. <>를 다이아몬드라고 한다 예를 들어 아래와 같이 쓸 수 있다. 

Box<String> Box = new Box<>();


컬렉션(collection)은 자료를 저장하기 위한 구조이다. 자바는 컬렉션 인터페이스와 컬렉션 클래스로 나누어 제공한다. 컬렉션은 int나 double과 같은 기초 자료형은 저장 할 수 없다. 클래스만 가능하다. 컬렉션은 제네릭을 사용한다. 


ArrayList는 동기화를 하지 않기 때문에 벡터보다 성능이 우수하다. 이외에도 컬렉션에는 Map, Set, Vector 등 다양한 자료 구조가 있다. 


람다식은 나중에 실행될 목적으로 다른 곳에 전달 될 수 있는 코드 블록이다. 이름 없는 메소드라고 할수 있다. 람다식은 메소드를 객체로 취급할 수 있는 기능이다. (argument) -> (body) 구문을 사용하여 작성한다. 


   Chapter 13 파일 입출력

스트림은 데이터의 종류에 따라 바이트 스트림과 문자 스트림이로 분류 할 수 있다. 바이트 스트림은 바이트 단위로 입출력하는 클래스들이며, 주로 이진 데이터를 읽고 쓰기 위해 사용된다. 바이트 스트림 클래스 이름에는 InputStream, OutputStream이 붙는다. 


문자 스트림은 문자 단위로 입출력하는 클래스이다. 자바는 기본적으로 유니코드를 사용한다. 자바에서는 유니코드를 처리하는 클래스들이 따로 준비되어있다. 문자 스트림 클래스 이름에는 Reader와 Writer가 붙는다. 


스트림은 운영체제의 자원을 많이 소모한다. 따라서 사용이 끝나면 반드시 닫아서 자원을 반환해야 한다. try-with-resources 구문 사용 권장. 


자바는 "객체 직렬화" 라고 하는 편리한 메커니즘이 있다. 객체를 파일에 저장하려면 객체가 가진 데이터들을 순차적인 데이터로 변환하는 절차가 필요하다 이것을 직렬화(serialization)이라 한다. 어떤 클래스가 직렬화를 지원하려면 Serializable 인터페이스를 구현하면 된다. 그리고 객체가 직렬화된 데이터를 읽어서 자신의 상태를 복구하는 것을 역직렬화(desirialization)이라 한다. 


File 클래스는 파일을 조작하고 검사하는 코드를 쉽게 작성하게 해주는 클래스이다. File객체는 파일이 아닌 파일 이름을 나타낸다. 


   Chapter 14 자바 스레드

프로그래머들은 하나의 어플리케이션 안에서 동시에 실행되는 여러 스레드를 만들수 있으며, 이 스레드들은 자바 런타임 시스템에 의해 동시에 실행된다. 


자바에서 스레드를 생성하여 작업을 실행하는 방법에는 두가지가 있다

  • Thread 클래스를 상속하는 방법 : run( )메소드에는 스레드가 수행해야할  작업 내용이 들어간다. 서브 클래스에서 인스턴스를 생성하고 start( )메소드를 호출하면 스레드가 실행된다.
  • Runnable 인터페이스를 구현하는 방법 : Thread 클래스를 상속하는 방법의 경우 다른 클래스를 상속 할 수 없는 단점이 있다. 자바에서는 단일 상속만 가능하기 때문이다. 이 경우 Runnable 인터페이스를 구현하는 방법을 이용한다. Runnable 인터페이스를 구현한 클래스에서 run( )메소드르 정의하면된다.
스레드들은 동일한 데이터를 공유하기 때문에 매우 효율적으로 작업할 수 있지만 스레드 간섭(thread interference)와 메모리 일치 오류(memory consistency error)가 발생할 수 있다. 이러한 오류를 막는 도구를 동기화(synchronization)이라 한다. 즉 공유된 자원 중에서 동시에 사용하면 안되는 자원을 보호하는 도구이다. 공유 데이터를 조작하는 메소드 앞에 synchronized 키워드를 붙인다. 

wait( ) 메소드는 어떤 일이 일어나기를 기다릴 때 사용하는 메소드이다. notify( )는 반대로 어떤 일이 얼어났을 때 이를 알려주는 메소드이다. 


반응형