본문 바로가기
1. Information Technology/1. Java

1. Java

by H232C 2020. 4. 13.

yaboong.github.io/java/2018/05/26/java-memory-management/

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io

jeong-pro.tistory.com/148

 

JVM 구조와 자바 런타임 메모리 구조 (자바 애플리케이션이 실행될 때 JVM에서 일어나는 일, 과정��

JVM(Java Virtual Machine) : 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체다. CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능하다. 즉, 운영체제 위에서 동작하는 프로세스로 자�

jeong-pro.tistory.com

codingplus.tistory.com/29

 

'Call by value'와 'Call by reference'의 차이

함수 호출 방법은 크게 두가지가 있다. Call by value(값에 의한 호출) Call by reference(참조에 의한 호출) 이를 설명하기 위해, 많은 교재에서는 그림으로 예시를 들고 있다. 예를 들어, 컵에 물을 채워�

codingplus.tistory.com

yaboong.github.io/java/2018/06/09/java-garbage-collection/

 

자바 메모리 관리 - 가비지 컬렉션

개요 Java 가비지 컬렉션에 대해서 공부한 내용을 정리해본다. Java 에서 메모리 관리는 어떻게 이루어지는지 이해하고 있으면 좋다. 자바 메모리 관리 - 스택 & 힙 를 먼저 읽는 것을 추천한다. 모�

yaboong.github.io

1. 데이터 타입에 따른 구분
 - 기본형 변수(자료의 실제 값을 저장) : 논리, 문자, 정수, 실수형 데이터
 - 참조형 변수(값이 저장되어있는 주소값을 저장) :참조변수는 값이 저장되어 있는 주소값 값으로 갖는다.

2. 선언위치에 따른 변수 타입 구분
 - 멤버 변수 : 클래스변수와 인스턴스 변수를 통틀어 부르는 용어이다.
 - 인스턴스 변수 : 클래스 영역에 선언되고 인스턴스 생성시 만들어짐 (각각의 인스턴스마다 다른 값을 가질 수 있으므로 인스턴스 생성이 필수이며 각 인스턴스마다 다른값을 가져야 할 떄 사용됨)
 - 클래스 변수 : 인스턴스변수 앞에 Static을 붙이면 클래스 변수가 됨 값을 공유하는 변수이며 클래스 로딩시 생성되며 클래스 이름, 변수 이름 이렇게 인스턴스 생성 필요없이 바로 쓸 수 있음
 - 지역 변수 : 메소드 내에 선언되며 메소드가 종료되면 사라진다.
 - 매개 변수 : 흔히 파라미터라고 불린다. 메소드에서 입력값을 받을 때가 있는데 그때 사용되는 변수를 매개변수

public class Variable {
    int a; 					// 타입(기본형변수), 위치(멤버변수의 인스턴스변수)
    static String b; 		// 타입(참조형변수), 위치(멤버변수의 클래스변수)
    void m(int c){ 			// 타입(기본형변수), 위치(매개변수이면서 지역변수)
        int d=c; 			// 타입(기본형변수), 위치(지역변수)
    }

    public static void main(String args[]) {
        int e=0; 								// 타입(기본형변수), 위치(지역변수)
        Variable v = new Variable();			// 타입(참조형변수), 위치(지역변수)
        v.m(e);									// 타입(인자값으로 0이 복사되어 넣어짐)
    }
}

 

3. 변수 : 변하는 값을 의미하며 int age; 등으로 생성하고 변수를 생성한다는 의미는 해당 자료형의 크기만큼의 메모리를 사용하겠다는 의미이다. 변수 이름은 숫자로 시작 불가하며 특수 문자중에는 '$','_'만 사용 가능하고 예약어(Reserved Word)는 사용 불가함

3.1. 정수 자료형
- 기본형 : 자바 언어에서 기본적으로 제공해주는 자료형, 메모리 크기가 정해져 있음 (정수, 문자, 실수, 논리형)
- 참조형 : 클래스 자료형, JDK에서 제공되는 클래스와 프로그래머가 정의하는 클래스를 말함
- 정수(byte, short, int, long), 문자(char), 실수(float, double), 논리형(boolean)

3.1. 문자 자료형 : 내부적으로 비트 조합으로 표현
- 인코딩 : 각 문자에 따른 특정한 숫자값(코드값)을 부여, 디코딩 : 인코딩의 역순
- 문자 세트 : 문자를 위한 코드값(숫자값)들을 정해놓은 세트 (ASCII 문자세트 등)
- ASCII : 1 바이트로 영문자, 숫자, 특수문자 등을 표현
- 유니코드 : 2 바이트로 한글과 같은 복잡한 언어를 표현하기 위한 문자셋(UTF-8, UTF-16이 대표적)

3.2. 실수형 : Double 자료형 -> 부동소수점 방식으로 표기

4. 상수와 리터럴, 형변환
- 상수(Constant) : 변하지 않는 수 -> Final sangNum 1; -> 변하지 않음
- 리터럴(Literal) : 프로그램 내에서 사용하는 모든 문자, 숫자, 논리 값(1, 15, 'A', true, false 등)
- 모든 리터럴은 상수풀(Constant Pool)에 저장되어 있음
- 리터럴(숫자, 문자, 불린 등) -> 상수 풀에 저장되어 있다가 로딩됨 -> 대입/복사 (int num = 3...)

5. 진법표현 : 2진수(0001), 8진수(001), 16진수(0xA)

6. 대입, 부호 산술, 복합대입, 증감 연산자
- 항과 연산자 
- 항(Operand):연상에 사용되는 값
- 연산자(Operator):항을 이용하여 연산하는 기호
- 항의 개수와 연산자 : 단항 ++, 이항 1+1, 삼항 (5>3)?1:0; (조건문과 비슷)

- 대입 연산자 : int age = 20;
- 부호 연산자 : 변수의 부호를 유지하거나 바꿈 (+,-) , 변수의 값을 변하게 하려면 대입연산자로 어사인해줘야 함

- 사칙 연산자 : + - + / %(나머지)
- 복합 대입연산자 : +=, =-, =*, =/ =%
- 증감, 감소 연산자 (++, --) : 앞뒤에 쓰느냐에 따라서 연산 순서가 달라짐
- val = ++num (num을 증감시키고 val에 값을 부여) / val = num++ (val에 값을 부여한 뒤 Num을 증감시킴)

7. 관계, 논리, 조건, 비트 연산자
- 관계 연산자 : < > >= <= == != 결과는 불리언값으로 뱉어냄
- 논리 연산자 : &&, ||, !(부정) 결과는 불리언값으로 뱉어냄
- 삼항 연산자
- int num=(5>3)?10:20;  (조건)?참:거짓;

- bit 연산자
- 1의보수 : 자리의 이진수 01001011(십진수로 75)의 1의 보수를 구하면 아래와 같다.

    11111111 (8+1=9자리)
 -) 01001011 (8자리)
    -----------
    10110100 (8자리)

01001011 의 모든 자리의 수를 반전시킨다.
10110100 (이것을 1의 보수라고 부른다)

- 2의보수
10110100 (이것을 1의 보수라고 부른다)
여기에 1을 더한다. 10110100 ---> 180
                      +) 00000001 ---> 1
                         -----------
                          10110101 ---> 181

 

master-hun.tistory.com/48

 

1의보수 2의보수에 대한 정리

1의보수와 2의 보수 알고넘어가기 ▶ 보수란? - 보수(補數)는 보충을 해 주는 수를 의미합니다. - 예를들어서 1에 대한 10의 보수는 9 , 4에 대한 10의 보수는 6, 3에 대한 17의 보수는 14의 개념입니다.

master-hun.tistory.com

- << >> >>> 시프트 (왼쪽은 곱하기, 오른쪽은 나누기 성질) : a<<2 (a변수의 2비트만큼 왼쪽으로 이동), a>>2(오른쪽으로 2비트 이동)
- >>> 숫자에 관계없이 0으로 표기
- 연산자 우선선위

일차식 > 단항 > 산술 > 비트이동 > 관계(<=, >=, <>), 관계(==, !=), 비트곱(&), 비트차(^), 비트합(|), 논리곱 (&&), 논리합(||), 조건(?:), 대입(=,++)


8. 제어문 (생략)

9. 객체지향 프로그래밍과 클래스
- 객체(Object) : 객체(Object)란 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른것과 식별 가능한 것을 말함
- 객체지향 프로그래밍 : 객체를 기반으로하는 프로그래밍, 객체를 정의하고, 객체의 기능을 구현, 객체간 협력 구현
 >>> 학생(먹는다 ? 애플/수박 | 간다 ? 학교/학원 | 탄다 ? 버스/자가용)
- 절차지향 : 시간이나 사건의 흐름에 따른 구형, C 언어가 대표적임
 >>> 학생 > 먹는다 > 애플 > 간다 > 학교 > 탄다 > 버스

- 클래스(Class)
- 객체를 코드로 구현한것, 객체지향 프로그램밍의 가장 기본 요소, 객체의 청사진(Blue Print)
- 멤버변수 : 객체가 가지는 속성을 변수로 표현, 멤버변수는 클래스 변수, 인스턴스 변수가 존재함
- 메서드 : 객체의 기능을 구현
- 객체의 코드화(클래스) > 붕어빵기계(클래스) > 붕어빵(인스턴스)
- class 파일 내의 public class 명과 파일명은 동일해야하면 public class 명은 유니크하다 (2개이상의 public class 사용 불가)
- 인스턴스명 = 참조변수

- 메서드 : 객체의 기능을 구현하기 위해 클래스 내부에 구현되는 함수
- 메서드를 구현함으로써 객체으 기능이 구현 됨, 메서드의 이름은 사용하는쪽에 맞게 명명하는것이 좋음 getStudentName() 등
- 함수에서 사용하는 메모리를 스택 메모리라고 함 -> 스택 메모리 (실행순서로 쌓이는 구조) main > addNum() 함수 > addnum 매개변수, 지역변수 > return > put .. > main
- 스택 메모리의 특징은 함수의 호출이 끝나면 메인만 남음 (함수가 호출되어 리턴후 메모리에서 사라짐)

10. 인스턴스, 힙 메모리
- 인스턴스 : 클래스로부터 생성된 객체, 힙메모리에 멤버변수의 크기에 따라 메모리가 생성, 클래스를 기반으로 new 키워드를 이영하여 여러개의 인스턴스를 생성 (각각 저장된 메모리 주소는 다름 = 물리적으로 다른 객체)
- 스택 영역의 메모리는 메소드 호출이 끝나면 사라지나 힙 영역에 보관되는 메모리는 메서드 호출이 끝나도 사라지지 않고 유지됨(주소를 잃어버려 가비지가 되어 가비지 콜랙터에 의해 지워지기 전 혹은 JVM이 종료되기 전까지)
- 각각의 인스턴스는 별개의 멤벼변수 주소를 갖는다.
- C, C++의 경우 메모리 free를 해줘야 하지만 Java의 경우 Garbage Collector가 자동으로 처리해줌 (스택, 힙메모리 정리)

- 객체(Object) : 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른것과 식별 가능한 것을 말함(객체는 속성과 동작으로 구성되어 있는데 속석은 각각의 필드이고 동작은 각각의 메소드를 말함)
- 클래스 : 객체를 프로그래밍 하기 위해 코드로 만든 상태
- 인스턴스 : 클래스가 메모리에 생성된 상태
- 멤버변수 : 클래스의 속성, 특성 (클래스의 속성 = 멤버변수)
- 메서드 : 멤버 변수를 이용해서 클래스의 기능을 구현
- 참조변수 : 메모리에 생성된 인스턴스를 가르키는 변수 (A a = new A();) -> a는 A 클래스를 인스턴스화한 메모리 주소를 같는 참조변수이다.
- 참조값 : 생성된 인스턴스의 메모리 주소값 (sysout(instance) -> 참조변수(인스턴스)가 가르키고있는 힙메모리의 가상주소)
- main 함수의 경우 별도의 main 전용 클래스에서 생성하는 것이 좋음

11. 생성자
- 생성자의 특징은 객체를 생성할 때만 부를수 있음 (new) 객체 생성 외에는 호출 불가능
- 인스턴스를 초기화하는 코드가 구현됨 (주로 멤버변수 초기화) -> 이니셜라이즈
- 반환 값이 없음, 상속되지 않음, 생성자는 클래스 이름과 동일
- 기본 생성자 : 하나의 클래스에는 반드시 하나 이상의 생성장가 존재해야 함, 프로그래머가 생성자를 구현하지 않으면 컴파일러가 생성자 코드를 넣어줌
- 기본 생성자는 매개변수가 없고, 구현부가 없음, 만약 클래스에 다른 생성자가 있는 경우 디폴트 생성자는 제공되지 않음
- 참조 자료형 : 기본자료형(int, long, float, double 등), 참조 자료형(String, Date, Student 등)
- 참조 변수를 선엄함 String name; 기본 자료형은 사용하는 메모리가 정해져있지만 참조 자료형은 클래스에 따라 다름

12. 정보은닉
- 변수, 메서드, 생성자에 대한 접근제어를 위해 접근 제어자 사용
- Public(모두 오픈), Private (클래스 내부에서만 사용), Protected(클래스 내부, 동일 패키지, 상위 클래스를 상속받은 클래스)
- Private 제어자 : private 변수를 외부에서 접근하게 하려면 public 메서드를 제공함 (통상 getter ,setter 사용), Default = 같은 패키지 내에서만 사용
- 클래스 내부 데이터를 잘못 사용하는 오류를 사전에 방지할 수 있음 (꼭 Private를 사용해야 하지는 않으나 필요시 사용)

13. This 키워드
- 자신의 메모리를 가리킴, 생성자에서 다른 생성자를 호출함(생성자 오버로딩), 인스턴스 자신의 주소를 반환
- 자신의 메모리를 가리킴 : Stack(Main > setYear() > this) -> Heap (Year)을 가리킴
- 생성자에서 다른 생성자를 호출

public Person(){

public Person(String name, int age){
	this.name = name; this.age=age;
    }
    
public Person getSelf() {
	return this; //자기 자신을  반환
    }
}

 

14. Static 변수, 메서드
- 여러 인스턴스가 하나의 값을 공유할 필요가 있음 -> 데이터 영역 메모리! (인스턴스 A, B, C -> Static 변수 1개!)
- Static 변수는 처음 프로그램이 로드될 데이터 영역에 생성됨 (스태틱 영역에 저장 Heap 아님!)
- 인스턴스의 생성과 상관없이 사용할 수 있으므로 클래스 이름으로 참조 Student.serialNum =100;
  클래스변수, 정적 변수라고 함 (스태틱/데이터 영역)
- 클래스 메서드, 정적 메서드라고도 함

15. 프로그램에서 변수의 유형
- 지역 변수(함수 내부에서 선언, 함수 내부에서만 사용, 스택, 함수가 호출될때 생성하고 함수가 끝나면 소멸),
- 멤버 변수(클래스 내부에서 사용하는 변수로 클래스변스, 인스턴스 변수가 존재함)
- 가비지 컬랙터가 메모리를 수거할 때 소멸됨)
- 클래스 변수(Static 예약어를 사용하여 클래스 내부에 선언, 클래스 내부에서 사용하고 private이 아니면 클래스 이름으로 다른 클래스에서 사용 가능, 
- 데이터 영역 : 프로그램이 처음 시작할 때 상수와 함께 스태틱 영역에 생성되고 프로그램이 끝나고 메모를 해제할 때 소멸됨)
- 스택 영역 : 기본형 변수 및 참조형 변수의 변수명(실제 인스턴스 주소값은 Heap 메모리에 저장되고 참조형 변수는 해당 메모리 주소를 가르키고 있음)
- 힙 영역 : 코드에서 new 명령을 통해 생성된 인스턴스 변수가 놓인다
- 힙 메모리에 저장된 데이터는 스택과 달리 메소드 호출이 끝나도 사라지지 않고 유지됨 -> 주소를 잃어버러 가비지가 되거나 JVM이 종료될 때까지

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io

16. Static 응용 (singleton Pattern)
- Singleton Patter : 객체지향 개발 디자인 패턴(Spring IoC Container가 Bean을 관리할 때 기본적으로 이 패턴을 사용)
- 소프트웨어 디자인 패턴에서 싱글턴 패턴을 따르는 클래스는, 생성자가 여러 차례 호출되더라도
- 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를
리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. (보통 스태틱 변수를 생성하여 구현함, 한개의 객체를 여러개의 객체에서 사용해야할때 씀)

17. 배열 (ArrayList : 기본 자료형 배열)
- 동일한 자료형의 순차적 자료구조, 배열 선언하기 int[] arr = new int[10]; int arr[] = new int[10]; / fix string으로 시작한다.
- 4 Byte * 10 = 40byte의 메모리 공간이 생성되며 생성자(int[10])의 주소를 참조변수에 넣어줌 -> sysout(arr) -> 참조변수가 가르키는 메모리 주소가 보임
- 배열은 0번째 부터 시작됨, length = 5 -> index = 0~length-1;
- 물리적 위치와 논리적 위치가 다른경우 -> 링크드 리스트 -> 찾아보기 (배열을 늘리고자할 때 편리함)
- 논리적(1,2,3) 물리적(ab - bc - fd)
- 배열의 크기를 늘려야 할 경우 -> 더큰 배열을 만들고 복사하는 방식으로 사용함 (보통은 넉넉하게 만듦)
- 배열은 연속되는 값이 존재해야함 중간의 값을 삭제한다면 뒤의 수를 앞으로 당겨줌
- arr[0] = 1, arr[1] = 2; sysout(arr[0]);  첨자 연산에 유리하다

18. 객체배열(ArrayList)
- 기본 자료형 배열과 참조 자료형 배열(객체 배열)
- 기본 자료형 : int[] arr = new int[10]; (빈값에 0이 들어감)
- 참조 자료형 : Book[] library = new Book[5]; (빈값에 Null이 들어감) -> 객체의 주소를 담는 공간! (기본 자료형과 다름! 주소값을 담는다!)
- 향상된 For문으로 사용 for(Book book : arrayTest ){ }

19. 다차원 배열 : 2차원 이상의 배열, 지도, 게임, 평명이나 공간을 구현할 때 사용
- int[][] arr = new int[2][3];  프로그래밍 하다보면 종종 쓸일이 있음 특히 화면을 표현할 때 (미로, 바둑, 체스 등)
- 논리적으로 행/열으로 보면 됨, 이차원 배열은 이중 포문, 삼차원 배열은 삼중포문을 사용해서 표현함

20 ArrayList 사용하기
- 자바에서 제공되는 객체 배열이 구현된 클래스, 객체 배열을 사용하는데 필요한 여러 메서드들이 구현되어 있음
- 주요 메서드 : boolean add(E e), int size(), E get(int index), E remove(int index), boolean isEmpty()

ArrayList list = new ArrayList();
list.add("arrayTest"); for(String s : list){sysout(s)}

 

21. 상속이란 (객체지향의 가장 두드러지는 특징 상속 다형성!)
- 상속, 다형성을 잘 이해하면 유지보수하기 쉽고 확장성이 좋은 프로그램을 만들 수 있음
- 클래스에서 상속의 의미 : 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속(inheritance) 받아서 속성이나 기능이 확장되는 클래스를 구현함
- 상속 : 이미 구현되어 있는 클래스를 상속받아서 해당 클래스의 기능을 사용하겠다. (중요! 일반적인 기능에 더해서 확장 기능을 추가할때 사용)
- 상속하는 클래스 : 상위 클래스 (parent class, base class, super class)
- 상속받는 클래스 : 하위 클래스 (child class, derived class, subclass)
- class B extends A {} A클래스가 B클래스에게 상속한다 = B클래스가 A클래스를 상속받는다.
- extends 뒤에는 하나의 클래스만 상속이 가능하다 (다중 상속이 안된다!)
- 상속을 사용하는 경우 (상위 클래스는 하위 클래스보다 일반적인 개념과 기능을 가짐, 하위클래스는 상위클래스보다 구체적인 개념과 기능을 가짐)
- class Mammal{} class Human extends Mammal{} (Mammal=포유류)
- class Customer{}, class Vip_customer extends Customer{}, class Gold_customer extends Customer{}
- 고객 등급에 따른 차별화된 서비스를 제공할 수 있음 고객의 등급에 따라 할인율 적립금이 다르게 적용,
- 변수 제어자 Private 사용시 상속 받아도 사용 못함 이떄는 Protected 사용
- 접근 제한자 확인(public protected, default, private)

22. 상속에서 클래스 생성 과정과 형변환
- 하위 클래스가 생성되는 과정 : 하위 클래스가 생성될 떄 상위 클래스가 먼저 생성됨 -> 상위 클래스의 생성자가 호출되고 하위 클래스의 생성자가 호출됨
- 하위 클래스의 생성자에게는 무조건 상위클래스의 생성자가 호출되어야 함
- 하위 클래에서 상위클래스의 생성자를 호출하는 코드가 없는 경우 컴파일러는 상위 클래스 기본 생성자를 호출하기 위한 super()를 추가함
- super()로 호출되는 생성자는 상위 클래스의 기본 생성자임
- 만약 상위 클래스의 기본생성자가 없는 경우(매개변수가 있는 생성자만 존재하는 경우) 하위 클래스는 명시적으로 상위 클래스의 생성자를 호출해야함
- 상위클래스 상속자가 기본적으로 매개변수가 필요하다면, 상속받는 하위클래스에서 명시적으로 생성자를 맞추고 super(매개변수); 처리해야함
- 상위클래스의 인스턴스가 먼저생성되고, 하위 클래스의 인스턴스가 생성
- 힙메모리 (상위 > 하위)
- Customer vc = new VIPCustomer(); //VIPCustomer는 이미 Customer의 성질을 모두 갖고있음

23. 오버라이딩
- 상위클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 동일한 이름의 메서드를 재정의할 수 있음
- 예제의 Customer 클래스의 calcPrice()와 VIPCustomer의 calcPrice() 구현 내용은 할인율과 보너스 포인트 적립내용부분의 구현이 다름
- 따라서 VIPCustomer 클래스는 calcPrice() 메서드를 재정의해야함

24 가상 메서드
- 메서드의 이름과 메서드 주소를 가진 가상 메서드 테이블에서 호출될 메서드의 주소를 참조함
- 메서드의 이름 = 참조변수의 주소, 메서드 이름이 같다 = 같은 메모리를 참조
- 상위클래스를 상속받은 하위클래스에서 메서드 오버라이딩을 수행하고 아래와 같이 인스턴스를 생성하였을때
- 상위클래스 test = new 하위클래스();
- test.오버라이딩메서드() -> 호출시 하위클래스에서 오버라이딩된 메서드가 호출됨 -> 이를 가상메서드의 호출이라고 함
- 메서드는 인스턴스화되면서 고유의 주소값을 가지게 되는데, 오버라이딩된 주소값은 상위클래스와 하위클래스가 다름 그리고 위와같이 만들어진 인스턴스는 하위클래스의
- 오버라이딩된 메서드를 호출하게 됨, 오버라이딩 하지 않은 메서드의 경우 상위클래스의 메모리 주소를 참조함!

25. 다형성(Ploymorphism)
- 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
- 같은 코드에서 여러 실행 결과가 나옴
- 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징중 하나 객체지향 프로그램의 유비보수성에 기본이되는 특징임

class Animal{
public void move() {
System.out.println("동물이 움직입니다.");
}
}

class Human extends Animal{
@Override
public void move() {
System.out.println("사람이 두발로 걷습니다.");
}
}

class Tiger extends Animal{
public void move() {
System.out.println("호랑이가 네발로 걷습니다.");
}
}

class Eagle extends Animal{
public void move() {
System.out.println("독수리가 날아 다닙니다.");
}
}

public class AnimalTest {
public static void main(String[] args) {
Animal hAnimal = new Human();
Animal pAnimal = new Tiger();
Animal eAnimal = new Eagle();

AnimalTest test = new AnimalTest();
test.moveAnimal(hAnimal);
test.moveAnimal(pAnimal);
test.moveAnimal(eAnimal);
}

public void moveAnimal(Animal a) {
a.move();
}



- 폴리모피즘 : 하나의 코드에 여러 자료형이 구현이되어 다른실행이 되는것 
- 다형성을 사용하지 않았을 경우 moveAnimal을 오버로딩하여 세개의 메서드를 만들었어야함
- 다양한 여러 클래스를 하나의 자료형(상위클래스)으로 선언하거나 형변환하여 각 클래스가 동일한 메서드를 오버라이딩 한경우,
- 하나의 코드가 다양한 구현을 실행할 수 있음
- 유사한 클래스가 추가되는 경우 유지보수에 용이하고 각 자료형 마다 다른 메서드를 호출하지 않으므로 코드에서 많은 if문이 사라짐

- 상속은 언제 사용할까? S-A관계(is a relationship :inheritance) 일반적인 개념과 구체적인 개념과의 관계 (보편 -> 구체)
- 상위 클래스 : 일반적인 개념의 클래스(예 포유류)
- 하위 클래스 : 구체적인 개념 클래스(예 사람, 원숭이, 고래)
- 단순히 코드를 재사용하는 목적으로 사용하지 않음

- HAS-A관계(composition):한 클래스가 다른 클래스를 소유한 관계 (괜찮은 코드를 가져다가 쓰기)
- 코드 재사용의 한 방법 Student가 Subject를 포함한 관계 
- class Student{ Subject majorSubjet = new Subject(); (다른 객체를 받아서 그 객체의 기능을 사용하는 것)

26. Abstract 추상 클래스
- 추상 클래스란? 추상 메서드를 포함한 클래스, 추상메서드(구현 코드가 없이 선언부만 있는 메서드)
- abstract 예약어 사용 : 추상 클래스는 new(인스턴스화)할 수 없음
- concrete class;
- 어떤 기능이 공통으로 사용되지않을 경우 상위 클래스에서는 해당 기능을 추상화시켜놓고 하위클래스에서 사용하게 책임을 전가함 -> 뎁스별로 다양하게 구성됨
- Computer(추상) -> Notebook(추상) type 구현 -> MyNotebook() Display 구현
- 추상 메서드 : 하위 클래스가 구현해야하는 메서드, 구현된메서드 : 하위 클래스가 공통으로 사용하는 기능의 메서드, 하위 클래스에서 오버라이딩하여 사용할수있다.

27. 추상 클래스 응용 - 템플릿 메서드(아주 흔하게 사용되는 메서드)
- 템플릿 : 틀이나 견본을 의미
- 템플릿 메서드 : 추상 메서드나 구현된 메서드를 활용해 전체의 흐름(시나리오)를 정의해놓은 메서드
- final로 선언하여 재정의할 수 없게함
- 템플릿 메서드 패턴 : 디자인 패턴의 일종, 프레임워크에서 많이 사용되는 설계 패턴, 추상 클래스로 선언된 상위 클래스에서 추상 메서드를 이용하여
- 전체 구현의 흐름을 정의하고 구체적인 각 메서드 구현은 하위 클래스에 위임함
- 하위 클래스가 다른 구현을 했다고해서 템플릿 메서드에 정의된 시나리오 대로 수행됨
- 프레임워크를 쓴다는건 ? 정해진 흐름에서 빈 공간을 채워넣는 것
- Spring Abstract 템플릿 메서드 참고
- final 예약어 : final 변수는 값이 변경될 수 없는 상수임 public static final double PI = 3.14;
- 오직 한 번만 값을 할당할 수 있음. final메서드는 하위 클래스에서 재정의(오버로딩)할 수 없음
- final 클래스는 더이상 상속되지 않음 ex)java의 String 클래스 -> 다른 클래스가 String class를 extends 불가

- public static final 상수값 정의하여 사용하기
- 프로젝트 구현 시 여러 파일에서 공유해야 하는 상수값은 하나의 파일에 선언하여 사용하면 편리함
Define.java -> public class Define{public static final int MIN = 1;} //
- public class UsingDefine {main(){ sysout(Define.MIN)}} // static으로 선언했음으로 인스턴스 생성을 하지않고 클래스 이름으로 불러올수있다.
- static 선언시 변수의 클래스명으로 호출 가능함!!


28. 인터페이스
- 인터페이스의 요소 : 추상메서드, 상수, 디폴트 메서드, 정적 메서드, private 메서드
- 인터페이스를 선언한다? public interface Calc { double PI = 3.14; int ERROR = -99999; // 멤버 변수들은 모두 컴파일 과정에서 상수화가됨
- int add(int num1, int num2); int substract(int num1, int num2); } //인터페이스에서 선언한 메서드는 컴파일 과정에서 추상 메서드로 변환됨 
- CompliteCalc implements Calc { add, substract 기능 구현} // 인터페이스에서 선언한 모든 메서드 구현 해야함 
- Calc calc = new CompleteCalc(); 인터페이스를 구현한 클래스는 인터페이스 타입으로 변수를 선언하여 인스턴스를 생성할 수 있으며
- 인터페이스는 구현 코드가 없기 때문에 타입 상속이라고도 함


29. 인터페이스를 활용한 다형성 구현
- 인터페이스를 클라인언트 프로그램에 어떤 메서드를 제공하는지 알려주는 명세 또는 약속
- 한 객체가 어떤 인터페이스의 타입이라 함은 그 인터페이스의 메서드를 구현했다는 의미
- 클라이언트 프로그램은 실제 구현 내용을 몰라도 인터페이스의 정의만 알면 그 객체를 사용할 수 있다. (인터페이스 명세!)
- 인터페이스를 구현해 놓은 다양한 객체를 사용함 - 다형성 -> JDBC를 구현한 오라클, MSSQL 라이브러리 등
- 언테페이스는 어플리케이션의 특성을 나타내는 껍데기 같은 존재 -> 이를 보고 어떻게 동작하는지 파악하고 구현하면 됨
- 클라이언트는 서버의 어떤 기능을 사용할때 해당 기능의 인터페이스 명세를 보지 기능의 내부까지 다 보지는 않음
- 인터페이스 명세를 알면 해당 기능을 사용할 수 있음!
- 이러이러한 모듈이 되려면 이러한 기능(인터페이스 명세)을 구현해서 써라
- 중요, 추상클래스는 하나만 상속받을 수 있음, 인터페이스는 여러개를 상속받을 수 있음

- JDBC : Connecton / Statement 등을 DB로 전달해야 함
- JDBC Connection, Statement는 인터페이스로 구현되어 있음
- 얘네들을 상속받는(extends) 애들은 각각의 벤더(Oracle, Mysql, MsSQL)등이다!
- 인터페이스 = ~해야한다는 명세 , 상속클래스 : 인터페이스의 명세대로 구현
- 외부에서 기능을 제공받거나 제공하는 경우 인터페이스를 제공 !
- 인터페이스와 다형성 구현하기

- 고객센터에서는 전화 상담을 하는 상담원이 있다. 일단 고객 센터로 전화가 오면 대기열에 저장됨. 상담원이 지정되기 전까지 대기 상태가 됨
- 각 전화가 상담원에게 배분되는 정책은 다음과 같이 여러 방식으로 구현됨
- 상담원 순서대로 배분
- 대기가 짧은 상담원 먼저 배분
- 우선순위가 높은(숙련도가 높은) 상담원에게 먼저 배분
- interface(getMessage()) -> RoundRobin, LastQue, Ratio, Fixed Policy, Get Policy (디자인패턴 중 스트레러직 패던이라고 함)


30. 인터페이스 요소
- 상수 : 선언된 모든 변수는 상수로 처리됨
- 메서드 : 모든 메서드는 추상 메서드
- 디폴트 메서드 : 기본 구현을 가지는 메서드, 구현하는 클래스에서 재정의할 수 있음 Java8
- 정적 메서드 : 인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드 Java8
- private 메서드 : 인터페이스 내에서 사용하기 위해 구현한 메서드, 구현하는 클래스에서 재정의할 수 없음 Java9

- 인터페이스는 구현 코드가 없으므로 하나의 클래스가 여러 인터페이스를 구현할 수 있음
- 디폴트 메서드의 이름이 중복되는 경우에는 재정의함

- 인터페이스 상속 : 인터페이스간에도 상속이 가능함 , 구현이 없으므로 extends 뒤에 여러 인터페이스를 상속받을 수 있음 
- 구현 내요잉 없으므로 타입 상속이라고 함

- 하나의 클래스를 상속받으면서 여러개 혹은 하나의 인터페이스를 임플레먼트 함
- 인터페이스가 다른 인터페이스를 상속을받아 이루어지는 경우 (타입상속이라고 함) interface x, interface y -> interface myInterface Extends x, y

- 상속과 인턴페이스 인플레먼트를 같이쓰는경우  Class BookShelf extends Shlf (extends), impletments Queue(Implement) 


31. Object 클래스
- Object 클래슨 자바의 최상위 클래스
- Object 클래스 : 모든 클래스는 object 클래스에서 상속 받음, 모든 클래스는 Object 클래스의 메서드를 사용할수있음, Object 클래서의 일부 메서드를 재정의하여 사용할수있음
Java.lang.Obejct 클래스 위치
- 코딩할때 import java.lang 패키지를 자동으로 import 시킴 
- Object 메서드를 오버라이딩 하는 방법
- equals() 메서드 : 두개의 인스턴스(객체)가 동일함을 논리적으로 재정의할수있음
- 물리적으로 동일함 : 같은 주소를 가지는 객체
- 논리적으로 동일함 : 같은 학번의 학생, 같은 주문번호의 주문
- Student s1 = new Student(100, "이상원");
- Student s2 = s1;  // s1과 s2는 물리적으로 같다. 같은 메모리를 참조하기 때문
- Student s3 = new Student(100,"이상원"); // s1과 s3는 논리적으로 같다.

- hashcode() 메서드의 반환값 : 인스턴스가 저장된 가상머신의 메모리 주소
- sysout(Lee.hashcode()); -> 123554869465

- clone() 메서드 : 객체의 복사본을 만듦, 기본틀로부터 같은 속성값을 가진 객체의 복사본을 생성할 수있음
- 객체지향 프로그래밍의 정보은닉에 위배되는 가능성이 있으므로 복제할 객체는 clonable 인터페이스를 명시해야 함

- finalize() 메서드 : 가비지 컬랙터가 한번 훑게함

32. String, Wrapper 클래스
- String 클래스 선언하기
- String str1 = new String("abc"); -> 힙 메모리에 어로케이션을 받겠다. -> 인스턴스가 저장되는 것과 동일
- Sting str2 = "abvc"; -> 리터럴(상수)풀에 있는 문자열을 가르킴 (int, chr, float 등의 상수풀 + static 상수풀)
- String은 immutable 한번 선언되거나 생성된 문자열을 변경할 수 없음
- String 클래스의 Concat()메서드 혹은 "+"를 이용하여 String을 연결하는 경우 문자열은 새로 생성됨
- String 클래스에서는 char을 배열로 나열하고 이것을 final로 설정해주기 떄문에 변경이 불가함

- Wrapper 클래스
- 기본형 : boolean, byte, char, short, int ,long, float, double
- wrapper : Boolean, Byte, Char, Short, Int, Long, Float, Double (대부분의 메서드가 오버라이딩되어있으며 C, C++에서 넘어온 개념이라고 함)

33. 컬랙션 프레임워크(자바의 여러 라이브러리를 모아놓은 종합 라이브러리) > 제네릭 프로그래밍(컬랙션 프레임웤에 적용되어 있음)
- 제네릭 프로그래밍이란? 변수의 선언이나 메서드의 매개변수를 하나의 참조 자료형이 아닌 여러 자료형으로 변환될 수 있도록 프로그래밍 하는 방식
- 실제 사용되는 참조 자료형으로의 변환은 컴파일러가 검증하므로 안정적인 프로그래밍 방식임
- public class GenericPrinter P private T meterial; // 제너릭 클랙스, 자료형 매개변수
- public void setMaterial(T material) { this.material = material;} public T getMaterial(){ return material;}
- T의 자료형은 변경될 수 있음

- 제너릭 메서드를 일반 클래스에서도 사용 가능하다.
- class Shape { public static <T, V> double makeRectangle(Pint<T,V>p1,PintMT,V> p2){}}
- class의 제너릭과 makeRectanggle 는 다름
- 제너릭 예제

// Meterial.java

package generic;

public abstract class Meterial {
	
	public abstract void doPrinting();

}

 

// Plastic.java

package generic;

public class Plastic extends Meterial{

	@Override
	public String toString() {
		return "재료는 플라스틱 입니다.";
	}

	@Override
	public void doPrinting() {
		System.out.println("플라스틱 프링팅 입니다.");
	}
	
}

 

// Powder.java

package generic;

public class Powder extends Meterial{

	@Override
	public String toString() {
		return "재료는 파우더 입니다.";
	}

	@Override
	public void doPrinting() {
		System.out.println("파우더 프링팅 입니다.");
	}
}

 

// GenericPrinter.java

package generic;

public class GenericPrinter<T extends Meterial>{ // extends Meterial로 Meterial을 extends 받지않은 클래스는 받지않도록 함
	//상위 추상 클래스에 기능을 넣어서 T 타입의 인스턴스가 기능을 사용할 수 있게함
	
	private T material;

	public T getMaterial() {
		return material;
	}

	public void setMaterial(T material) {
		this.material = material;
	}

	@Override
	public String toString() {
		return material.toString();
	}
	
	public void printing() {
		material.doPrinting(); // 추가된 기능
	}

}

 

// GeniricPrinterTest.java

package generic;

public class GenericPrinterTest {

	public static void main(String[] args) {
		GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
		//GenericPrinter<Powder> powderPrinter = new GenericPrinter<>(); 생성자의 <> 생략가능
		Powder powder = new Powder();
		powderPrinter.setMaterial(powder); //powderPrinter에 powder Setting
		System.out.println(powderPrinter);
		powderPrinter.printing();
		
		GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
		//GenericPrinter<Powder> powderPrinter = new GenericPrinter<>(); 생성자의 <> 생략가능
		Plastic plastic = new Plastic();
		plasticPrinter.setMaterial(plastic); //powderPrinter에 powder Setting
		System.out.println(plasticPrinter);
		plasticPrinter.printing();
		
	}
}



34. 컬랙션 프레임워크
- 프로그램 구현에 필요한 자료구조와 알고리즘을 구현해놓은 라이브러리
java.util 패키지에 구현되어있음
- 개발에 소요되는 시간을 절약하고 최적화된 라이브러리를 사용할 수 있음
- Collection 인터페이스와 Map인터페이스로 구성됨
= 컬렉션 인터페이스 : 객체의 관리를  위해 선언된 인터페이스로 필요한 기본 메서드가 선언되어 있음

- 하위 List, Set 인터페이스가 있음 -> List(ArrayList, Vector, LinkedList), Set(HashSet, TreeSet);
- Collection은 하나의 객체를 위한 자료형

- Map 인터페이스 : 쌍으로 이뤄진 객체를 관리하는데 필요한 여러 메서드가 선언되어 있음
- Map을 사용하는 객체는 Key-Value 쌍으로 되어있고 Key는 중복될 수 없음 (Map - Hashtable,HashMap, TreeMap, Properties)

- 자료구조 : ArrayList(연속된, 선형 자료구조 논리적, 물리적으로 연속됨) -> 중간에 데이터가 빠지면 뒤에 객체를 당겨옴 -> 시간이 걸림 -> 장점 : 검색이 빠름 (산술연산)
-> 배열을 늘리고자할 때 복사를 하거나 해야함, -> ArrayList, Vector
- 링크드리스트(논리적으로는 선형, 물리적으로는 연속되지않음, 떨어져있음) -> 중간 데이터가 빠지면 링크를 변경해줌 -> 간단함 -> 단점 : 검색이 느림
-> 링크드리스트를 늘리고자 할때 메모리 공간이 허용한 만큼 늘릴수 있음 -> LinkedList
- Stack : 위로 쌓이는 자료구조 LIFO-> Last In First Out -> 가장 상위를 Top, 꺼내기 pop
- Que : FIFO First in First Out -> 맨앞을 front, 뒤를 rear -> 들어가는것 enQueued, 나오는것 deQue
- hash : 검색을 위한 자료구조, hash(key) -> 위치를 알려줌
- hashtable에서 index 위치를 알려줌 -> 산술연산이됨 빠름 -> 검색이 빠름 -> 키는 중복되지 않음
- hashtable에 극장 좌석 0~99까지 있다. 15번이 영화보러 왔다 어디로 앉히냐? -> 15번 찾아서 위치를 찾기 
- Binary Tree : Parent 하위에 Child가 비교보다 작거나 같음
- Binary Search Tree : 검색을 위한 함수 작은것은 Left Side, 큰것은 Right side


36. 리스트 인터페이스
- 컬랙션 하위 인터페이스, 객체를 순서에 따라 저장하고 관리하는데 필요한 메서드가 선언된 인터페이스
- 배열의 기능을 구현하기 위한 메서드가 선언됨, ArrayList, Vector, LinkedLIst
- ArrayList와 Vector : 일반적으로 Array List를 더 많이 사용, Vector은 멀티쓰레드 프로그램에서 동기화를 지원
- 동기화:두개의 쓰레드가 동시에 하나의 리소스에 접근할 때 순서를 맞춰서 데이터 오류를 방지함
- Capacity(배열의 용량)와 Size(배열의 엘리먼트 사이즈)는 다른 의미림 

- ArrayList와  LinkedList 둘다 자료의 순차적 구조를 구현한 클래스
- ArryaList는 배열을 구현한 클래스로 논리적 순서와 물리적 순서가 동일
- LinkedList는 논리적으로 순차적인 구조지만 물리적으로는 순차적이지 않을 수 있음\
- LinkedList 구조 : 자료(다음요수의 주소)->자료(다음요수의 주소)->자료(다음요소의 주소)
- LinkedList 추가시 -> 기존 연결을 신규 엘리먼트 연결 -> 기존 연결 끊음
- 삭제시 : 기존연결 끊고 다음 엘리먼트에 연결

- Stack : Las in First Out Lifo 맨 마지막 추가된 요소가 가장 먼저 꺼내지는 구조
- 이미 구현된 클래스가 제공됨, Arryalist나 LinkedList로 구현할 수 있음, 게임에서 무르기, 최근 자료 가져오기 등에 구현

- Queue " FIFO" 구조 먼저저장된 자료를 먼저 꺼내는 구조

37. Set 인터페이스
- Iterrator로 순회하기 : Collection의 개체를 순회하는 인터페이스
- iterator() 메서드 호출 : Iterator ir = memberArrayList.iterator();
- Iterrator에 선언된 메서드 : boolean hashNext() 이후에 요소가 더 있는지 체크하는 메서드, 요소가 있다면 true 반환/ E Next() 다음의 요소를 반환
- Set 인터페이스
- 컬랙션 하위의 인터페이스, 중복을 허용하지 않음(때로는 만들어줘야함), List는 순서기반의 인터페이스지만 set은 순서가 없음
- get(i) 메서드가 제공되지 앟음(Itrator로 순회), 저장된 순서와 출력순서는 다를수있음
- 아이디 주민번호 사번 등 유일한 값이나 객체를 관리할 떄 사용, HashSet, TreeSet 클래스
- HashSet 클래스 : 중복을 허용하지 않으므로 저장되는 객체의 동일함 여부를 알기위해 equals()와 hashCode() 메서드를 재정의해야함
- TreeSet 클래스 : 객체의 정렬에 사용되는 클래스, 중복을 불허하고, 오름차순이나 내림차순으로 객체를 정렬함,
- 내부적으로 이진 검색 트리로 구현되어 있음, 이진 검색 트리에 자료가 저장될 때 비교하여 저장될 위치를 정함, 객체 비교를 위해
- Comparable이나 Comparator 인터페이스를 구현해야 함
- Comparable은 CompareTo() 메서드를 구현, 매개변수와 객체 자신을 비교
- Comparator는 Compare()메서드를 구현, 두개의 매개변수를 비교
- TreeSet 생성자에 Comparator가 구현된 객체를 매개변수로 전달
- TreeSet treeSet = new TreeSet(new Member()); // new Member()값을 주어야 함!
- 일반적으로 Comparable을 더 많이 사용 -> 이미 Comparable이 구현된 경우 Comparator를 이용해서 다른 정렬방식을 정의할 수 있음

2.33. Map 인터페이스 
- Key: Value 의 쌍의 자료구조
- Conllection 인터페이스와 다름, 자료를 쌍으로 페어로하여 관리해할 때 사용함
- Key-Value Pair의 객체를 관리하는데 필요한 메서드가 정의됨, Key는 중복될 수 없음
- 검색을 위한 자료구조 , Key를 이용하여 값을 저장하거나 검색, 삭제할때 사용하면 편리함
- 내부적으로 hash방식으로 구현됨 index = hash(key) // index는 저장 위치
= key가 되는 객체는 객체의 유일성함의 여부를 알기위해 equals()와 hashCode() 메서드를 재정의함

- HashMap 클래스 : Map인터페이스를 구현한 클래스중 가장 일반적으로 사용하는 클래스
- HashTable 클래스는 자바2부터 제공됨 클래스로 Vector 처럼 동기화를 제공함
- Pair자료를 쉽고 빠르게 관리할 수 있음
- TreeMap 클래스 : Key 객체를 정력하여 Key-value를 pair로 관리하는 클래스
- Key에 사용되는 클래스에 Comparable, Comparator 인터페이스를 구현, Java에 많은 클래스들은 이미 Comparable이 구현되어 있음
- 구현된 클래스를 Key로 사용하는 경우 구현할 필요 없음 


37. 내부 클래스
- 내부 클래스와 람다식
- 내부 클래스 : 클래스 내부에서 구현한 클래스(중첩된 클래스), 클래스 내부에서 사용하기 위해 선언하고 구현하는 클래스
- 주로 외부 클래스 생성자에서 내부 클래스를 생성
- 인스턴스 내부 클래스 (외부 클래스 멤버 변수와 동일, 외부 인스턴스 변수, 외부 전역 변수, 외부 클래스를 먼저 만든 후 내부 클래스 생성)
- 정적 내부 클래스 (외부 클래스 멤버 변수와 동일, 외부 전역 변수, 외부 클래스와 무관하게 생성)
- 지역 내부 클래스 (메서드 내부에구현, 외부 인스턴스 변수, 외부 전역 변수, 메서드를 호출할 떄 생성)
- 익명 내부 클래스 (메섣 내부에 구현, 변수에 대입하여 직접 구현, 외부 인스턴스 변수, 외부 전역 변수, 메서드를 호출할 떄 생성되거나 인터페이스 타입 변수에 대입할때
- new 예약어를 사욯하여 생성 (어너니머스 내부 클래스)

38. 람다식
- 람다식으란 ? 자바에서 함수형 프로그래밍을 구현하는 방식, 클래스를 생성하지 않고 함수의 호출만으로 기능을 수행함
- 함수형 인터페이스를 선언함, 자바 8부터 지원되는 기능, 함수형 프로그래그래밍은 함수호출만으로 기능을 수행 -> 오류가 적어짐, 안정성 상승
- 함수형 인터페이스에서 제공 (인터페스랑?라이브러리라고 보면됨)

- 순수함수를 구현하고 호출, 매개변수만을 사용하도록 만든 함수로 외부 자료에 부수적인 영향이 발생하지 않도록 함
- 입력받은 자료를 기반으로 수행되고 외부에 영향을 미치지 않으므로 병렬처리등에 가능 
- 안정적인 확장성있는 프로그래밍 방식

= 람다식 문법 이클립스참고
- 함수를 변수처럼 사용하는 람다식..
- 프로그램에서 변수는 자료형에 기반하여 선언하고(int a); 매개변수로 전달하고(int add(int x, int y);) 메서드의 반환값으로 사용 return num;
- 암다식은 프로그램 내에서 변수처럼 사용할 수 있음

39. 스트림 (자바io에서 이야기하는 스트림과 별개임)
- 자료의 대상과 관계없이 동일한 연산을 수행할 수있는 기능(자료의 추상화)
- 배열, 컬렉션에 동일한 연산이 수행되어 일관성 있는 처리 가능 (배열을 전체를 합한다거나, 곱한다거나 하는 연산 등)
- 한번 생성하고 사용한 스트림은 재사용 불가
- 스트림연산은 기존 자료를 변경하지 않음
- 중간 연산과 최종 연산으로 구분됨 (중간연산 -> 조건에 맞는 자료를 꺼내온다거나 -> 최종연산은 마지막 연산값)
- 최종 연산이 수행되어야 모든 연산이 적용되는 지연 연산 (중요)

- 중간연산 : filter(), map()
- 조건에 맞는 요소를 추출(filter)하거나 요수를 변화함(map)
문자열의 길이가 5이상인 요소만 출력하기
sList.stream().filter(s->s.length*(>=5).forEach(s0>sysout(s)); (filter 중간연산, foreach 최종연산)
customerList.stream().map(c->c.getName()).forEach(s->sysout(s)); (map 중간연산, foreach 최종연산)

- 최종연산 : 스트림은 한번 만들어지면 재사용이 필요하다면 스트림을 재사용해야함
- 스트림의 자료를 소모하면서 연산을 수행, 최종 연산후에 스트림은 더이상 다른 연산을 적용할 수 없음
- forEach() 요소를 하나씩 꺼내옴, count() 요소의 개수, sum() 요소의 합, 이 외도 여러가지 최종연산이 있음

40. 예외처리
- 오류란 무엇인가? 컴파일오류(프로그램 코드 작성 중 발생하는 문법적 오류), 실행오류(실행중인 프로그램이 의도하지 않은 동작을 하거나 프로그램이 중지되는 오류)
- 자바는 예외 처리르 통해 프로그램의 비정상종료를 막고 log를 남길 수 있음
- 문법오류는 IDE에서 거의 잡아주나 실행오류의 경우 IDE가 잡아주지 못함 -> 예외 처리를 통해 해결
- 예외처리에서 가장 중요한 부분은 로그를 상세히 남겨야한다는 점이다. 이를 통해 문제를 해결할수있음
- 시스템오류 : 가상머신에서 발생, 프로그래머가 처리불가, 동적 메모리를 다 사용한 경우, Stack Over Flow 등
- 예외(Exception) ; 프로그램에서 제어할 수 있는 오류, 읽으려는 파일이 없는 경우, 네트쿽이나 소켓 연결 오류, 자바 프로그램에서는 예외에 대한 처리를 수행함
- 모든 예외 클래스의 최상위 클래스는 Exception 클래스가 존재함
- IOException(FileNotFound, SocketException..), RuntimeException(Arithmetic, IndexOutofBounds..)
- IO 클래스에서는 대부분 예외처리를 해줘야함

- try- catch 문으로 예외처리 하기
- try{
예외가 발생할 수 있는 코드 부분
}catch(처리할 예외타입 e){ // 클래스타입으로 매개변수를 받음
try블록 안에서 예외가 발생했을 때 수행되는 부분
} finally{
예외 발생 여부와 상관없이 항상 수행되는 부분, 리소스를 정리하는 코드를 주로 씀
}

- try, with, resources 문
- 리소스를 자동으로 해제하도록 제공해주는 구문
- 해당 리소스가 AutoCloseable을 구현한 경우 close()를 명시적으로 호출하지 않아도 try{} 블록에서 오픈된 리소스는 정상적인 경우나 예외가 발생한 경우 모두 자동으로
- close()가 호출됨, 자바 7부터 제공됨, FileInputStream의경우 AutoCloseable을 구현하고 있음

- 예외처리 미루기
- Throws를 사용하여 예외처리 미루기 try{} 블록으로 예외처리하지 낳고 메서드 선언부에 throws를 추가
- 예외가 발생한 메서드에서 예외처리를 하지않고 이 메서드를 호출한 곳에서 예외 처리를 한다는 의미
- main()에서 throws를 사용하면 가상머신에서 처리됨


41. 자바 입출력 스트림
- 입출력 스트림이란? 네트웍에서 자료의 흐름이 물과 같다는 의미에서 유래
- 다양한 입출력 장치에 독립적으로 일관성 있는 입출력 방식 제공
- 입출력이 구현되는 곳에서는 모두 I/O 스트림을 사용 : 키보드, 파일 , 디스크, 메모리 등
- 입출력 스트림 구분?
- I/O 대상 기준 : 입력 스트림, 출력 스트림 
- 자료의 종류 : 바이트(몇바이트씩 쓸것이냐~), 문자 스트림(따로 만들어놓음)
- 스트림의 기능 : 기반, 보조 스트림
- 입력 스트림 : 대상으로부터 자료를 읽어들임 (FileInputStream, FileReader, BufferedInputStream, BufferedReader 등)
- 출력 스트림 : 대상으로부터 자료를 출력하는 스트림 (FileOutputStream, FileWriter, BufferedOutpuStream..)

- 바이트 단위 스트림과 문자 단위 스트림 (inputStream, outputStream 등)
- 바이트 : 바이트 단위로 자료를 읽고 씀 (FileInpuStream. outpu..)
- 문자 : 2바이트씩 처리

- 기반스트림 : 다상에 직접 자료를 읽고 쓰는 기능의 스트림
- 보조스트림 : 직접 일고 쓰는 기능은 없고 추가적인 기능을 제공해주는 스트림 기반 스트림이나 또 다른 보조 스트림을 생성자의 매개변수로 포함함



42. 문자단위 입출력 스트림
- Reader, Write 문자 단위로 읽고 쓰는 최상위 스트림
- FIleReader, InputStreamReader, BufferReader(속도빠름).. 동일이름Witer

- 보조 스트림
- 기반 스트림을 보조하는 스트림 -> 1byte, 2byte 등의 읽기 쓰기 변경 등
- FilterInputStream, FilterOutputStream이 최상위 클래스
- 기반 +보조 +보조 
- Buffered Stream, DataInputStream, OutputStream


43. 직렬화 (Serialization)
- 인스턴스 상태를 그대로 저장하거나 네트워크로 전송하고 이를 다시 복원(역직렬화 Deserialization)하는 방식
- ObjectInputStream과 ObjectOutputStream 사용
- 보조 스트림의 한 종류

- 마크인터페이스 : 직렬화는 인스턴의 내용이 외부로 유출되는 것이므로 프로그래머가 객체의 직렬화 가능 여부를 명시함
- 구현 코드가 없는 mark interface

class Person implements Serializable { //직렬화 하겠다는 의도를 표시
String name; String job;
}



44. 그외 입출력 클래스와 데코레이터 패턴
- file 클래스 : 파일 개념을 추상화한 클래스, 입출력 기능은 없고 파일의 속성, 경로, 이름등을 알 수 있음
- RandomAccessFile 클래스 : 입출력 클래스 중 유일하게 파일 입출력을 동시에 할 수 있는 클래스
- 파일 포인터가 있어서 일고 쓰는 위치의 이동이 가능함, 다양한 자료형에 대한 메서드가 제공됨

- 데코레이터 패턴 : 자바 입출력 스트림은 데코레이터 패턴을 사용함
- 실제 입출력 기능을 가진 객체(컴포넌트)와 그 외 다양한 기능을 제공하는 데코레이터(보조슽트림)을 사용하여 다양한 입출력 기능을 구현
- 상속보다 유연한 확장성을 가짐, 지속적인 서비스의 증가와 제거가 용이함

45. 쓰레드 구현하기
- 쓰레드란? Process:실행중인 프로그램, OS로부터 메모리를 항당 받음
- Thread 실제 프로그램이 수행되는 작업의 최소 단위, 하나의 프로세스는 하나 이상 Thread를 가지게 됨
- Process (Thread, Thread) -> 멀티 쓰레드, Process(Thread) 싱글 쓰레드
- 스케쥴러는 쓰레드의 CPU를 할당해서 수행하도록 함

 

jdm.kr/blog/69

 

자바 쓰레드 기초(Java Thread Basic) :: JDM's Blog

이번엔 Java Thread에 대해 알아보고자 합니다. 시작합니다! Java Thread Definition 자바 쓰레드Java Thread의 정의를 알기 전에 프로세스Process에 대해 알아야 합니다. 보통 우리가 만드는 프로그래밍 언어Ja

jdm.kr

 

jdm.kr/blog/72

 

자바 Runnable를 이용해 쓰레드 만들기 (Java Runnable Interface) :: JDM's Blog

저번 포스팅에서 얘기했던대로 이번엔 Runnable 인터페이스를 이용한 쓰레드 작성 방법에 대해 알아고보자 합니다. Runnable 인터페이스(Runnable Interface) 기본적인 Runnable 인터페이스의 사용 방법은 ��

jdm.kr

dailyworker.github.io/java-thread/

 

Java Thread - 자바 쓰레드

개요해당 장에서는 멀티 스레드 프로그래밍의 개념을 잡기 위해서 프로세스와 쓰레드에 대한 내용을 학습한다. 블로그의 내용은 “자바의 정석 개정 3판”을 정리하였다.

dailyworker.github.io



- 사용법 이클립스

- 멀티 쓰레드 프로그래밍 : 동시에 여러 개의 쓰레드가 수행되는 프로그래밍, 쓰레드는 각가의 작업공간(Context)를 가짐
- 공유 자원이 있는 경우 race Condition이 발생,
- Critical Section에 대한 동기화(Synchronization)의 구현 필요
- 공유된 자원을 차례로 사용하지않고 동시에 쓰기 시작할 경우 값이 깨질수있음 -> 동기화(순서대로 처리)가 필요
- 세마포어(크리티컬 섹션에 락을 건다). 락이걸렸을때는 다른 프로세스에서는 작업이 안됨

- Thread 우선순위
- Thread.MIN_PRIORITY(=1) ~ Thread.MAX_PRIORITY(=10)
- 디폴트 우선순위 : Tread.NORM_PRIORITY(=5)
- setPriority(int newPriority)
- int getPriority(). 우선순위가 높은 Thread는 CPU 배분을 받을 확률이 높음

- 멀티쓰레드 : 두개이상은 쓰레드가 동시 접근하게되는 리소스
- 이 리소스 영역을 critical section이라고하고 동시에 접근하게되면 실행 결과를 보장할수 없음
- thread간의 순서를 맞추는 동기화가 필요
- 동기화 : 임계 영역에 여러 쓰레드가 ㄷ접근하는 경우 한 쓰레드가 수행하는 동안 공유 자원을 락하여 다른 쓰레드의 접근을 막는다.
- 동기화를 잚못 구현하면 데드락에 빠질수 있음
- 키를 가진 쓰레드가 동작 -> 세마포어 동작 -> 순차적으로 임계영역에 접근
- 자바에서 동기화 구현 : Synchronized 수행문, 메서드를 이용
- synchronized (참조형 수식){}  // 참조형 수식에 해당되는 객체에 lock을 건다.

- synchronized 메서드
- 현재 이 메서드가 속해있는 객체에 lock을 건다.
- synchronized 메서드 내에서 다른 synchronized 메서드를 호출하지 않는다. (Deadlock 방지)

- 데드락 : Thread1은 Thread2의 L2를 기다림, Thread2는 Thread1의 L1을 기다림,
- L1 needs L2 and L2 needs L1 = 데드락 -> 방지하기위해, Syncronized 내에 외부 syncronized 호출 금지

- wait() : 리소스가 더이상 유효하지 않을 경우 리소스가 사용 가능할때까지 쓰레드를 non runnable 상태로 전환
- Wait된 상태의 쓰레드는 noifify가 호출될떄0까지 기다림
- notify : wait 하고있는 Thread 중 한 Thread를 Runnable 한 상태로 꺠움(아무 쓰레드나 꺠움)
- notifyAll() ; wait()하고있는 모든 Thread가 runnable 한 상태가 되도록 함, norify()보다 nofifyLl()을 사용하기를 권장
- 특정 쓰레드가 통지를 받도록 제어할 수 없으므로 모두 깨운 후 스케쥴에 CPU를 점유하는 것이 좀더 공평하다고 함

 

ㅇ 자바 예제 코드 : github.com/h232ch/java

 

h232ch/java

java basic. Contribute to h232ch/java development by creating an account on GitHub.

github.com

 

댓글