지네릭스

○ 지네릭스 : 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크(compile - time type check)를 해주는 기능

객체 별로 다른 타입을 지정해서 쓸 수 있게 하는 기능

객체의 타임을 컴파일 시 체크 -> 객체의 타입 안정성 높이고 번거로움 줄임

타입 안정성을 높임 : 의도하지 않은 타입의 객체가 저장되는 것을 막고, 저장된 객체를 꺼내올 때 원래 타입과 다른 타입으로 잘못 형 변환되어 발생할 수 있는 오류 줄여줌

지네릭스 장점

(1)   타입 안정성 제공

(2)   타입 체크와 형 변환 생략 가능 -> 코드 간결해짐

 

○ 지네릭 클래스 선언

클래스 옆에 <T> 붙이기

class Box<T>{

T item;

void setItem(T item){ this.item = item; }

T getItem(){ return item; }

}

 

■ <T> 안의 T : 타입 변수(Type)

T 말고도 E(Element_요소), K(Key_), V(Value_)

임의의 참조형 타입을 의미하는 것!

Object타입 대신 원하는 타입 지정하면 됨

Box<String> b = new Box<String>(); // 이런 식

 

지네릭스 용어

□ Box<T> : 지네릭 클래스. “T Box”, “T Box” 라고 읽음

□ T : 타입 변수 or 타입 매개변수\

□ Box : 원시 타입(raw type)

지네릭 타입 호출 : 매개변수에 타입을 지정하는 것

대입된 타입 = 매개변수화 된 타입 : 지정된 타입, <> 안에 들어가는 타입

 

지네릭스의 제한

모든 객체에 대해 동일하게 동작해야 하는 static 멤버에 타입 변수 T 사용 불가능

T는 인스턴스 변수로 간주 됨

지네릭 타입의 배열을 생성하는 것 허용하지 않음

지네릭 배열 타입의 참조변수 선언은 가능하지만 new T[10]; 처럼 배열 생성 불가능

instanceof 연산자와 new 연산자는 컴파일 시점에 타입 T가 뭔지 정확히 알아야 함

지네릭 배열 생성해야 한다면 newInstance() 와 같이 동적으로 객체 생성하는 메서드로 배열 생성하거나 Object 배열 생성해 복사한 다음 T[]로 형 변환

 

○ 지네릭 클래스의 객체 생성과 사용

객체 생성 시 참조변수와 생성자에 대입된 타입(매개변수화 된 타입)이 일치해야 함

두 지네릭 클래스의 타입이 상속관계에 있고, 대입된 타입이 같으면 괜찮음

Box<Apple> applebox = new Box<Apple>(); //

Box<Apple> applebox = new Box<Grape>(); // 안 됨

Box<Fruit> applebox = new Box<Apple>(); // 가능. 다형성

 

■ JDK1.7 이상부터는 추정 가능한 경우 타입 생략 가능

 

○ 제한된 지네릭 클래스

지네릭 타입에 extends 붙이면 특정 타입의 자손들만 대입 가능

class FruitBox<T extends Fruit> { … } // 해당 클래스는 Fruit 클래스 자손들은 받을 수 있음

인터페이스를 구현해야 하더라도 extends 사용(implements 아님)

클래스와 인터페이스를 함께 구현하는 자식인 경우 &로 둘 연결해 줌

class FruitBox<T extends Fruit & Eatable> extends Box<T>{ }

// Box<T>의 자손 클래스 FruitBox는 타입 매개변수로 Fruit Eatable 을 구현한 자손 클래스 받음

 

와일드 카드

?

■ <?> : <? extends Object>

<> : <Object>

■ static 메서드에서는 타입 매개변수 T를 사용할 수 없음

지네릭 타입이 다른 것 만으로는 오버로딩이 성립하지 않음! -> 단순 메서드 중복 정의 에러임

static 메서드에 지네릭 타입이 다른 매개변수 쓴다고 해서 되는 게 아님

    ?의 상한과 하한_extends super

■ <? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능

■ <? super T> : 와일드 카드의 하한 제한. T와 그 조상들만 가능

■ <?> : 제한 없음. 모든 타입이 가능. =<? extends Object>

□ static Juice makeJuice(FruitBox<? extends Fruit> box){ …. return new Juice(box); }

호출 Juicer.makeJuice(fruitBox); (클래스명.메서드명(매개변수))

Juicer 클래스 안에 static 메서드로 지정되어 있다고 할 때

이런 식의 static 메서드의 매개변수를 상한을 정함

Fruit의 자손들만 받는 FruitBox 클래스를 매개변수로 받게 함

□ static <T> void sort(List<T> list, Comparator<? super T> c){}

호출 Collections.sort(appleBox.getList(), new AppleComp());

Collections.sort() 메서드!

List <T> list : 정렬할 대상

Comparetor <? super T> : 정렬할 방법. 지네릭 하한 제한 걸려있는 와일드 카드 사용됨

Comparator의 지네릭을 해당 타입 매개변수 조상까지 쓸 수 있다는 것

Comparator<Apple> 이라면

Comparator<Object>, Comparator<Fruit>, Comparator<Apple> 된다는 말이다

Comparator<Grape>는 안됨! 조상이 아니니까!(형제…. 클래스 ㅋㅋ 잖아)

 

○ 지네릭 메서드

메서드의 선언부에 지네릭 타입이 선언된 메서드

반환타입 바로 앞에 <T> 써줌

지네릭 클래스에 정의된 타입 매개변수와 지네릭 메서드에 정의된 타입 매개변수는 전혀 별개!

지네릭 메서드는 지네릭 클래스가 아닌 클래스에서도 정의 가능

■ static 멤버에는 타입 매개변수 사용할 수 없지만 메서드에 지네릭 타입 선언하고 사용하는 것은 가능함

메서드에 선언된 지네릭 타입은 매개변수의 지네릭 타입을 뽑아내서 써주는 것

메서드 내에서만 지역적으로 사용되므로 지역변수를 선언한 것과 같다고 생각하면 됨

내부 클래스에 선언된 타입 문자가 외부 클래스의 타입 문자와 같아도 구별 가능

static Juice makeJuice(FruitBox<? extends T> box){…}

→ static <T extends Fruit> Juice makeJuice (FruitBox<T> box){…}

호출 Juicer.<Fruit>makeJuice(fruitBox); or Juicer.<Apple>makeJuice(appleBox);

대입된 타입을 컴파일러가 추측할 수 있다면 대입된 타입 생략 가능

Juicer.makeJuice(fruitbox);

대입된 타입을 생략할 수 없는 경우는 참조변수나 클래스 이름 생략할 수 없음

같은 클래스 내 멤버끼리는 참조변수나 클래스이름(this, 클래스이름)을 생략하고 메서드 이름만으로 호출 가능하지만, 대입된 타입이 있을 때는 반드시 써줘야 함(규칙임)

매개변수 타입이 요란할 때 코드 간략히 할 수 있음

public static void printAll(ArrayList<? extends Products> list, ArrayList<? extends Products> list2){ } 이런 것들을

è public static <T extends Product> void printAll(ArrayList<T> list, ArrayList<T> list2){ }

이렇게 간략화 할 수 있음

복잡한 와일드 카드의 지네릭 메서드 분석하기

□ public static <T extends Comparable<? super T>> void sort(List<T> list){}

매개변수 안의 List <T> : 타입 T를 요소로 하는 List 매개변수로 허용

지네릭 메서드 선언의 <T extends Comparable <? super T>>

→ <T extends Comparble> : T Comparable 구현한 클래스

→ Comparable<? super T> : ComparableT와 그 조상 타입을 비교하는 인터페이스임

List T를 사용한 Collections이고 그 T Comparable 구현한 클래스이며, Comparable T와 그 조상들을 비교하는 인터페이스! 가 되는 것

와일드 카드부터 내려놓고 차근차근 뜯어보자

 

지네릭 타입의 형 변환과 지네릭 타입 제거

○ 지네릭 타입의 형 변환

지네릭 타입과 넌지네릭 타입 간의 형 변환은 항상 가능 -> 그러나 경고 발생!

Box box1 = null;

Box<Object> box2 = null;

box1 = (Box)box2; // 경고 발생 (원시 타입으로 형 변환)

box2 = (Box<Object>)box2; // 경고 발생 (지네릭 타입으로 형 변환)

대입된 타입이 다른 지네릭 타입 간의 형 변환은 불가능

Box<String> box1 = null;

Box<Object> box2 = null;

box1 = (Box<String>)box2; // 에러

box2 = (Box<Object>)box2; // 에러

와일드 카드 사용한 대입 타입간 형 변환은 가능 -> 다형성

Box<? extends Object> box2 = new Box<String>(); // 다형성 적용

Box <String > box2 = new Box <? extends Object >(); // 가능은 하지만 경고 발생

, 지네릭 타입 다른 것들은 형 변환 직접 X 와일드 카드 포함된 지네릭으로 형 변환 가능

와일드 카드가 사용된 지네릭 타입끼리도 상속관계가 있다면 형 변환은 가능

 

○ 지네릭 타입의 제거

컴파일러는 지네릭 타입을 이용해 소스 파일을 체크하고, 필요한 곳에 형 변환을 넣어준 뒤 지네릭 타입 제거함

제거과정

(1)   지네릭 타입의 경계(bound) 제거

(2)   지네릭 타입을 제거한 후 타입이 일치하지 않으면 형 변환 추가

와일트 카드가 포함되어 있는 경우 적절한 타입으로 형 변환 추가 됨

14 컬렉션 프레임웍_List

1.     ArrayList

○ 데이터 저장순서 유지되고 중복 허용

Object배열을 이용해 데이터를 순차적으로 저장

○ 한 요소가 삭제될 때마다 빈 공간을 채우기 위해 나머지 요소들이 자리이동을 함

■ remove로 삭제 시 for구문으로 접근하게 되면 접근 변수를 뒤에서부터 감소시켜 역방향으로 지워야 됨

자리이동 발생해도 영향 받지 않도록 해야 함

ArrayList 생성 시 저장 요소 개수 고려하여 실제 저장할 개수보다 약간 여유 있게 해야 함

생성할 때 지정한 크기보다 더 많이 저장하면 크기가 늘어나지만 시간이 많이 걸림

기존 ArrayList를 복사하고 새 ArrayList 생성해 복붙하고 새 객체 넣고 그렇게 되므로 ㅜ

ArrayList Vector 같은 것들은 배열을 이용한 자료구조

읽고 저장하는 데, 임의 접근 하는 데는 효율이 좋음

새로 생성된 배열로 데이터 복사하면서 크기를 늘리므로 비효율적

 

2.     LinkedList

○ 배열 이용한 구조의 단점

(1)   크기를 변경할 수 없음

(2)   비순차적인 데이터 추가 또는 삭제에 시간이 많이 걸림

○ 배열 단점 보완하는 LinkedList

배열은 모든 데이터가 연속적으로 존재함

링크드 리스트는 불연속적으로 존재하는 데이터를 서로 연결한 형태

링크드 리스트의 각 요소들은 자신과 연결된 다음 요소에 대한 참조와 데이터로 구성

class Node{

Node next;

Object obj;

}

삭제!

삭제하고자 하는 요소의 이전요소가 삭제하고자 하는 요소의 다음 요소를 참조하도록 변경하기만 하면 됨

배열처럼 데이터 이동 위해 복사하는 과정이 없어 처리속도 빠름

추가

새로운 요소를 생성한 다음 추가하고자 하는 위치의 이전 요소의 참조를 새로운 요소에 대한 참조로 변경하고, 새로운 요소가 그 다음요소 참조하도록 함

단 방향이므로 이전요소에 대한 접근은 어려움

 

Doubly Linked List & Doubly circular Linked List

■ Doubly Linked List

링크드 리스트에 이전 요소에 대한 참조를 하는 참조변수 하나 더 추가

□ LinkedList는 더블 링크드 리스트로 구성됨 -> 낮은 접근성을 높임

각 요소에 대한 접근이 조금 더 쉬움

class Node{

Node next;

Node previous;

Object obj;

}

■ Doubly circular Linked List

더블 링크드 리스트의 첫 번째 요소와 마지막 요소가 서로를 가리키는 것

맨 앞과 맨 뒤를 연결하여 순환하는 자료구조

 

ArrayList LinkedList 비교

 

 

다루고자 하는 데이터의 개수가 변하지 않는다면 ArrayList가 나을 것

데이터 개수 변경이 잦다면 LinkedList가 나을 수도

두 클래스를 조합하여 사용하는 것도 좋음

처음 작업 전 데이터 저장에는 ArrayList 사용하다가 작업할 때 LinkedList로 옮겨서 추가 삭제 작업 하면 됨

컬렉션 프레임워크는 서로 변환 가능한 생성자 제공하므로 가능함

ArrayList aList = new ArrayList();

LinkedList lList = new LinkedList(aList);

이런 식

 

1.     Stack & Queue

1)    Stack

순차적으로 데이터를 추가하고 삭제

■ ArrayList같은 배열 기반 컬렉션이 적합

■ Last In First Out

수식 계산, 수식 괄호 검사, 워드프로세스의 undo/redo, 웹 브라우저의 뒤로/앞으로

2) Queue

데이터 꺼낼 때 항상 첫 번째 데이터 삭제하므로 LinkedList로 구현하는 것이 적합

■ First In First Out

최근사용문서, 인쇄작업 대기목록, 버퍼

3) PriorityQueue

저장한 순서에 관계 없이 우선순위가 높은 것부터 꺼내는 것

■ null 저장 불가능

저장공간으로 배열 사용하고, 각 요소를 힙(이진트리의 일종 부모 자식간 대소차이가 있음)이라는 자료구조로 저장

숫자 뿐 아니라 객체를 저장할 수 있으며 객체 대소 비교 방식 지정해줘야 함

4) Deque

■ queue의 변형

양 쪽 끝으로 추가 삭제 가능한 자료구조

구현은 ArrayList, LinkedList로 구현 가능

 

2.     Iterator, ListIterator, Enumeration

○ 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스

○ 접근하는 방법의 표준화

1)    Iterator

컬렉션에 저장된 요소들을 읽어오는 방법의 표준화

■ Iterator(Iterator를 구현한 클래스의 인스턴스)를 반환하는 iterator() 메서드 정의 되어있음

컬렉션 클래스에 대해 iterator() 호출 -> Iterator 얻음 -> while 문이나 반복문으로 컬렉션 클래스의 요소를 읽어옴 (읽어 올 것이 있는지 확인해야 됨)

표준화! 이므로 다형성을 위해 참조변수의 참조형은 List로 하고 생성되는 실 인스턴스는 자식 클래스로 생성하면 다양한 컬렉션끼리 호환도 되므로, 그렇게 쓰자

■ Map 인터페이스 구현한 컬렉션 클래스는 key value값을 쌍으로 저장하므로 iterator() 직접 호출 불가능

keyset()이나 entrySet()과 같은 메서드들로 키와 값을 각각 따로 Set 형태로 얻어와 그 set iterator() 호출하여 Iterator 얻음

Map map = new HashMap();

List mvList = map.entrySet().iterator();

List mkList = map.keySet().iterator();

 

■ List 클래스들은 저장 순서 유지하기 때문에 Iterator 이용해 읽어온 결과도 저장 순서와 동일

Set 클래스들은 저장 순서 유지 안 하므로 Iterator도 저장 순서와 같지 않음

 

2)    ListIterator & Enumeration

■ ListIterator : Iterator에 양방향 조회기능 추가(List 구현한 경우만 사용 가능)

■ Enumeration : Iterator의 구버젼

둘 다 뒤()에 읽어올 것 있는지 has… 메서드로 확인해야 함

 

3.     Arrays

○ 배열을 다루는 데 유용한 메서드가 정의되어 있는 클래스

1)    배열의 복사

■ copyOf() : 배열 전체 복사

■ copyOfRange() : 베열 일부 복사해 반환. 범위의 끝은 포함X

2)    배열 채우기

■ fill() : 배열 모든 요소를 지정된 값으로 채움

■ setAll() : 배열 채우는데 사용할 함수형 인터페이스를 매개변수로 받음

함수형 인터페이스를 구현한 객체를 매개변수로 지정하던가 람다식으로 지정해야 함

Arrays.setAll(arr, ()->(int) (Math.random()*5)+1);

3)    배열의 정렬과 검색

■ sort() : 배열 정열할 때 사용

■ binerySearch() : 배열에 지정된 값이 저장된 위치 찾아서 반환. 배열이 정렬된 상태에서만 가능

이진검색! : 배열 검색 범위를 반복적으로 죽여가며 검색하므로 빠르지만 정렬이 필요

4)    문자열 비교와 출력

출력

□ toString() : 일차원 배열에서 사용

□ deepToString() : 다차원 배열에서 사용. 모든 요소를 재귀적으로 접근해 구성

비교

□ equals() : 일차원 배열에서 사용 가능

□ deepEquals() : 다차원 배열 비교

다차원 배열에서 equals() 사용하면 배열에 저장된 배열 주소를 비교하게 됨

5)    배열을 List로 변환

■ asList() : 배열을 List에 담아 반환

매개변수 타입이 가변인수라 배열 생성 없이 저장할 요소들만 나열하는 것도 가능

■ asList() 가 반환한 List의 크기를 변경할 수 없으므로 새 리스트 생성해서 반환된 리스트 넣어 새로 생성

List list = new ArrayList(Arrays.asList(1,2,3,4,5));

6)    parallelXXX(), spliterator(), stream()

■ parallel로 시작하는 메서드들 : 여러 쓰레드가 작업을 나누어 처리하도록 함

■ spliterator() : 여러 쓰레드가 처리할 수 있게 하나의 작업을 여러 작업으로 나누는 Spliterator 반환

■ stream() : 컬렉션을 스트림으로 변환

 

4.     Comparator & Comparable

Arrays.sort() 호출 시 정렬된 것은 Charater클래스가 Comparable 구현해서 가능한 것(equals())

Comparable & Comparator

■ Comparable : 기본 정렬 기준을 구현하는 데 사용

compareTo() 메서드가 정의되어 있음

Comparable인터페이스!

이 것을 구현한 클래스들은 기본적으로 오름차순으로 정렬

이 것을 구현한 클래스들의 객체를 비교하는 것은 sort로 바로 정렬, 비교 가능

■ Comparator : 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용

compare() 메서드를 제정의하여 사용

Comparable 구현한 클래스 아니라면 정렬비교 기준이 없으니 Comparator을 만들어 기준을 만들어 준다는 느낌

Comparator compare() 메서드를 오버라이딩 -> Comparable의 객체를 생성해 그 객체에 있는 compareTo()메서드 사용하여 compare()을 재정의!

■ Arrays.sort() 메서드는 배열 정렬 시 Comparator 지정하지 않으면 기본 저장하는 객체에 구현된(Comparable 구현한 객체) 내용에 따라 정렬됨

static void sort(Object[] a) // 객체 배열에 저장된 객체가 구현한 Comparable에 의한 정렬

static void sort(Object[] a, Comparator c) // 지정한 Comparator에 의한 정렬

대소문자 구분 없는 Comparator : 상수 형태로 제공됨

String.CASE_INSENSTIVE_ORDER을 컴퍼레이터 자리에 넣으면 됨

내림차순 구현

String에 구현된 compareTo() 결과에 *-1 해주거나

비교하는 객체의 위치를 바꿔서 뒤에 있는 애와 앞의 애 자리 바꿔 compareTo써주면 됨

 

14   컬렉션 프레임웍

1.     개괄

1)    ArrayLiust

배열 기반

데이터의 추가와 삭제에 불리

순차적인 추가 삭제는 가장 빠름

임의의 요소에 대한 접근성이 뛰어남

2)    LinkedList

연결 기반

데이터의 추가와 삭제에 유리

임의의 요소에 대한 접근성이 좋지 않음

3)    HashMap

배열과 연결이 결합된 형태

추가, 삭제, 검색, 접근성 모두 뛰어남

검색에 최고 성능

4)    TreeMap

연결 기반

저열ㄹ과 검색(범위 검색)에 적합

검색 성능 HashMap보다 떨어짐

5)    Stack

Vector 상속 받아 구현

6)    Queue

LinkedList Queue 인터페이스 구현

7)    Properties

Hashtable 상속받아 구현

8)    HashSet

HashMap 이용해서 구현

9)    TreeSet

TreeMap 이용해서 구현

10)  LinkedHashMap . LinkedHashSet

HashMap HashSet에 저장순서 유지기능 추가

 

2.     컬렉션 프레임웍

○ 데이터군을 저장하는 클래스들을 표준화한 설계

○ 핵심 인터페이스

■ Collection – List / Set + Map

 

1.     각 인터페이스를 살펴보자

1)    Collection 인터페이스

■ ListSet의 조상

저장된 데이터 읽고, 추가, 삭제 등 기본적인 메서드 제공

2)    List 인터페이스

중복을 허용하면서 저장순서가 유지되는 컬렉션 구현

■ Vector, ArrayList, LinkedList

■ index가 있음

3)    Set 인터페이스

중복을 허용하지 않고 저장순서가 유지되지 않는 컬렉션 클래스

■ HashSet, SortedSet, TreeSet

4)    Map 인터페이스

키와 값을 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스 구현

키 중복 X, 값 중복 O

■ Hashtable, HashMap, LinkedHashMap, SortedMap, TreeMap

■ values() 의 반환 타입 Collection, keyset() 의 반환타입 Set

→ value는 중복 허용하므로 Collection으로 반환

→ key는 중복 허용하지 않으므로 Set으로 반환

Set은 중복 허용하지 않는 컬렉션 프레임 웍임

5)    Map.Entry 인터페이스

■ Map의 내부 인터페이스

■ Map에 저장되는 key-value쌍을 다루기 위해 내부적으로 Entry 인터페이스를 정의함

 

13 예외처리

l  예외 처리

○ 프로그램 오류

프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우

발생시점에 따라 구분

n  컴파일 에러 : 컴파일 시에 발생하는 에러

n  런타임 에러 : 실행 시에 발생하는 에러

n  논리적 에러 : 실행은 되지만, 의도와 다르게 동작하는 것

 

컴파일 에러

n  소스코드(*.java) –컴파일 -> 클래스 파일(*.class)

n  컴파일러가 기본적인 검사 수행하여 오류 알려줌

n  오류 수정하여 컴파일 마치면 클래스파일 생성되고 실행할 수 있음

 

런타임 에러

n  실행 도중 발생할 잠재적 오류까지 컴파일러가 검사할 수 없음

n  프로그램의 실행 도중 발생할 수 있는 모든 경우의 수 고려해 대비

n  에러와 예외 두 개가 있음

u  에러 : 메모리 부족이나 스택오버플로우 같이 일단 발생하면 복구할 수 없는 심각한 오류코드에 의해 수습 불가능

u  예외 : 발생하더라도 수습될 수 있는 비교적 덜 심각한 오류코드에 의해 수습 가능

n  예외는 적절한 코드로 비정상 종료 막을 수 있음

 

예외 클래스의 계층 구조

n  Exception 클래스와 그 자손들

u  외부의 영향으로 발생할 수 있는 것들

u  프로그램의 사용자들의 동작에 의해 발생하는 경우가 많음

u  FileNotFoundException, DataFormatException 같은 것들

n  RuntimeException 클래스와 그 자손들

u  프로그래머의 실수에 의해 발생 -> 자바의 프로그래밍 요소와 관련

u  IndexOutBoundsException, NullPointerException, ClassCastException, ArithmeticException

 

l  예외 처리하기 try – catch

예외처리 : 프로그램 실행 시 발생할 수 있는 예외 상황에 대한 대비 코드 짜는 것

try-catch

n  하나의 try블록에 여러 종류의 예외 처리할 수 있도록 하나 이상의 catch블록 올 수 있음

n  예외 종류랑 일치하는 catch문만 실행되고 나머지는 패스

n  일치하는 예외가 없으면 예외 처리 되지 않음

try{
	//예외가 발생할 가능성 있는 문장 넣기
}catch(Exception1 e1){
	// Exception1 발생 했을 경우, 이를 처리하기 위한 문장 넣기
}catch(Exception2 e2){
	// Exception2 발생 했을 경우, 이를 처리하기 위한 문장 넣기
} catch(ExceptionN eN){
	// ExceptionN 발생 했을 경우, 이를 처리하기 위한 문장 넣기
}
// 참조변수도 잘 바꿔줘야 함

 

try-catch문에서의 흐름

n  try블록에서 예외 발생했을 경우

(1)   발생한 예외가 일치하는 catch블럭 있는지 확인함

(2)   일치하는 catch블럭 찾으면 catch블럭 내 문장 수행 후 전체 try-catch문 빠져나가 다음 문장 실행

(3)   일치하는 catch블럭 못 찾으면 예외 처리 안됨

n  try블록에서 예외 발생하지 않았을 경우

(1)   catch블럭 거치지 않고 전체 try-catch문 빠져나가서 수행 계속함

n  try 블록에서 예외 발생하면 예외 발생 위치 이후 try블럭 안에 있는 문장 실행 한하므로 코드 범위 잘 선택해야 함

 

finally블럭

n  try-catch문에서 예외 발생 여부에 상관 없이 실행되어야 할 코드

try{
        // 예외 발생할 가능성 있는 문장들 
}catch(Exception1 e1){
        // 예외 처리 문장
}finally(
        // 예외 발생 여부에 상관없이 항상 수행되어야 하는 문장
        // try-catch문 맨 마지막에 위치
)

n  try 블록이나 catch 블록 문장 수행 중에 return문 만나도 finally블럭 문장 수행됨

 

예외 발생과 catch블럭

n  catch문 안에 괄호 속 예외와 try문에서 발생한 예외를 instanceof해서 catch블럭 찾음

n  Exception 클래스 타입은 모든 예외의 조상이므로 catch에 선언 안된 것은 이 블록으로 옴먼저 만나는 catch문이 일치하면 뒤에 catch문 실행 안되므로 젤 큰 예외 클래스는 마지막에 넣자

n  printStackTrace() & getMessage()

u  printStackTrace() : 예외 발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지 화면에 출력함

u  getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지 얻음

u  catch구문 괄호 안에 선언한 예외 참조변수로 메서드에 접근 가능

n  멀티 catch블럭

u  ‘ | ‘ 기호 이용해 한 catch문에 다중 예외 넣음

u  try {…} catch(Exception1 e1 | Exception2 e2){ … }

u  멀티 catch블록의 ‘ | ‘ 기호로 연결된 예외 클래스가 조상자식 관계면 컴파일 에러!조상만 선언해도 되는 것이니까

 

l  예외 발생시키기

키워드 throw

n  프로그래머가 고의로 예외 발생 시키기

(1)   연산자 new를 이용해 발생시키려는 예외 클래스 객체 만들기

(2)   키워드 throw를 이용해 예외 발생

n  Exception 인스턴스 생성할 때 생성자에 String 넣어주면 이 String Exception 인스턴스 메세지로 저장됨 -> getMessage()로 가져올 수 있음

 

RuntimeException과 그 자손 클래스

n  프로그래머가 실수해서 발생하는 것! -> 따로 굳이 예외 처리 안해도 됨

n  컴파일러가 예외처리 강제하지 않음 -> unchecked 예외

n  컴파일러가 예외 처리 확인하는 Exception 클래스들은 checked 예외

 

l  메서드에 예외 선언

메서드 선언부에 throws 사용해 메서드 내에서 발생할 수 있는 예외 적어줌

n  이 예외 뿐 아니라 자손 타입 예외도 발생할 수 있음

n  메서드 사용 시 메서드 선언부를 보고 어떤 예외들이 처리되어야 하는지 명시하는 역할

 

예외 처리 떠맡기기

n  메서드 사용하는 쪽에 이에 대한 처리를 강요하는 용도로 함

n  자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 용도임

n  어느 한 곳에서 반드시 try-catch로 예외처리 해 주어야 함

 

l  자동 자원 반환 –try-with-resources

JDK 1.7부터 등장한 입출력 관련 클래스랑 사용하면 좋은 구문

n  입출력에 사용되는 클래스 중 사용한 후 꼭 닫아줘야 하는 것들을 닫아줌

n  자원 반환 해줘야 하는 것을 자원 반환해 줌

 

try-catch-finally 개선한 구문

n  finally 구문에서 try-catch문 넣어서 자원 반환하면 코드 복잡함

n  try 블록과 finally 블록 모두 예외 발생하면 try 블록 예외는 무시됨

n  이런 것들을 개선함

 

try-with-resources

n  try문의 관호에 객체 생성하는 문장 넣어주면 이 객체는 따로 close() 호출 안 해도 try블럭 벗어나면 자동으로 close() 호출함

n  AutoCloseale 인터페이스 구현한 객체를 자동으로 close() 호출할 수 있음

n  괄호 안에 두 문장 이상 넣을 경우 ‘ ; ‘로 구분

try(FileInputStream fis = new FileinputStream(“score.dat”) ; 
DataInputStream dis = new DataInputStream(fis)){
….
}catch(Exception1 e1){
}

 

억제된 예외

n  두 예외가 동시에 발생할 수 없음

è 실제 발생한 예외와 억제된 예외로 두 예외를 다룸

è 억제된 예외에 대한 정보는 실제 발생한 예외에 저장됨

n  억제된 예외와 관련된 메서드

u  void addSuppressed(Throwable exception) : 억제된 예외 추가

u  Throwable[ ] getSuppressed() : 억제된 에외(배열) 반환

 

l  사용자 정의 예외 만들기

Exception클래스 상속받아서 나의 예외 클래스 만들기 -> checked 예외가 되는 거지

n  Exception class String 받아 메시지 저장 가능 -> String 받는 생성자 추가해줘야 됨

RuntimeException 클래스 상속받아 만들면 unchecked 예외가 됨

 

l  예외 되던지기 (exception re-throwing)

한 메서드에서 발생한 예외가 여럿인 경우 -> 메서드 자신과 사용자 둘에서 양쪽에서 나눠 처리

n  몇 개는 try-catch문으로 메서드 내에서 자체로 처리

n  나머지는 선언부에 지정하여 호출된 메서드에서 처리

 

자신이 예외를 처리한 후 인위적으로 다시 발생시켜 호출 메서드에서 처리하도록 함

n  try-catch문을 사용해서 예외 처리 해주고 메서드 선언부에 발생할 예외를 throws에 지정해줌

n  반환값 있는 return문의 경우

u  catch블록에도 return으로 반환값 써줄 수 있음

u  catch문에서 예외 되던지기 해서 호출한 메서드로 예외 전달하면 return문 없어도 됨

n  finally 블록 내에서도 return문 사용할 수 있음! 결국 finally return문 값이 반환됨

 

l  연결된 예외(chained exception)

한 예외가 다른 예외 발생시키게 하는 것

n  원인 예외가 다른 예외를 발생시킴

n  예외를 하나의 큰 분류 예외로 묶어 다루되, 조상관계로 만들지 않는 방법

n  checked 예외를 unchecked 예외로 바꿀 때도 씀

 

initCause()

n  Throwable 클래스에 정의되어 있는 메서드들

□ Throwable initCause() (Throwable cause) : 지정한 예외를 원인 예외로 등록

□ Throwable getCause() : 원인 예외를 반환

■ 예외 생성한 뒤에 initCause 예외를 다른 예외의 원인 예외로 등록 후 throw로 던짐

■ 예외를 큰 분류로 묶어 다룰 수 있음

 

○ RuntimeException(Throwable cause)

■ 원인 예외를 등록하는 생성자

■ checked 예외를 unchecked 예외로 바꾸어 예외 처리를 선택적으로 함

■ RuntimeException으로 Exception 예외를 감싸는 것

 

12 추상클래스와 인터페이스

l  추상클래스 abstract

m  추상클래스

n  미완성 메서드를 포함한 클래스(완성 메서드랑 변수 포함 가능!)

n  자기 자신으로 인스턴스 생성 불가능 -> 상속을 통한 자손 메서드에 의해서만 완성될 수 있음

n  class 앞에 abstract 붙임!

abstract class Parent{ }

 

m  추상메서드

n  선언부만 작성하고 구현부는 작성하지 않은 미완성 메서드

n  실제 상속 받는 클래스에서 구현하도록 비워두고 어떤 기능을 수행할 지만 주석처리로 알려줌

n  abstract 리턴타입 메서드이름( );

abstract int showShow();

                   { } <- 이거 붙이는 순간 일반 메서드로 취급

n  상속 받은 자손 클래스는 오버라이딩을 통해 조상인 추상메서드를 모두 구현해 줘야 됨구현 다 안하고 남겨두면 그 자손 클래스도 추상 클래스로 정의해야 됨

 

m  추상클래스 작성

n  추상클래스도 생성자가 있어야 함

n  추상클래스 내의 메서드들이 클래스 내의 추상 메서드 사용 가능

n  자손클래스에서 추상메서드를 반드시 구현하라고 강요하기 위해 작성!그냥 메서드는 상속되고 추상메서드는 반드시 오버라이딩 해야 함

 

l  인터페이스

m  인터페이스

n  일종의 추상클래스이지만 추상클래스보다 추상화 정도가 높음

n  오직 추상메서드와 상수만 멤버로 가질 수 있음일반 메서드, 변수 안됨!

 

m  인터페이스 작성

n  class 대신 interface 사용

n  접근 제어자로 public, default 사용 가능

n  제약사항

u  모든 멤버 변수는 public static final이며 생략 가능 (상수만 가능하고 접근제어자 정해져 있으니까!)

u  모든 메서드는 public abstract이고, 생략 가능(추상메서드만 가능하니까! 그리고 static 메서드와 default 메서드는 예외)

 

m  인터페이스 상속

n  인터페이스는 인터페이스로부터만 상속받을 수 있음

n  다중 상속 가능

n  최고 조상이 없음

n  자손 인터페이스가 조상 인터페이스에 정의된 모든 멤버 상속 받음

 

m  인터페이스 구현

n  자기 자신 그 자체로 인스턴스 생략 불가능 -> 자신을 상속받은 클래스로 인해 구현됨

n  extends 대신 implements 사용 (구현한다!는 의미)

n  구현하는 인터페이스 메서드 중 일부만 구현하면 -> 추상클래스로 선언해야 됨!

n  오버라이딩 할 때 조상 메서드보다 넓은 범위의 접근 제어자를 지정해야 함

 

m  인터페이스를 이용한 다중 상속

n  두 개의 클래스로부터 상속 받아야 한다면, 두 조상 클래스 중 비중 높은 쪽을 상속받고 낮은 것은 내부클래스로 하거나어느 한쪽의 필요한 부분만 뽑아 인터페이스로 만들어 구현

n  클래스는 둘 다 만들되, 한 클래스를 인터페이스로 따로 만들어 클래스의 메서드를 인터페이스 메서드로 오버라이딩!

class Scanner{ … }

class Copymachine{ 
…
	void method1();
	int method2();
… }

interface Icopymachine{
…
	void method1();
	int method2();
… }

class Multifunction_printer extends Scanner{} implements Icopymachine{
	Copymachine cm = new Copymachine();
	void method1(){
		cm.method1();
	}
	int method2(){
		cm.method2();
	}          
}

뭐 이런식?

 

m  인터페이스를 이용한 다형성

n  해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스 참조 가능인터페이스 타입으로 형 변환도 가능

n  메서드의 메개변수 같은 것으로 인터페이스 사용해서, 이를 구현하는 클래스들을 매개변수로 보낼 수 있음

n  리턴 타입을 인터페이스로 하여, 인터페이스 구현한 클래스를 리턴 할 수 있음

n  분산환경 프로그래밍에서 좋음 -> 사용자 컴퓨터에 설치된 프로그램을 변경하지 않고 서버 측 변경만으로 사용자가 새로 개정된 프로그램 사용 가능

 

m  인터페이스의 장점

n  개발 시간 단축 가능인터페이스 구현한 클래스의 인스턴스 멤버 접근으로 코드 중복을 막음(꺼내 쓰는 것)

n  표준화 가능

n  서로 관계 없는 클래스들에게 관계를 맺어줄 수 있음공통점이 없는 상속 관계에서 상속 체계 유지하고 공통점 부여

n  독립적인 프로그래밍 가능인터페이스 이용해 특정 데이터베이스에 종속되지 않은 프로그램 작성 가능

 

m  인터페이스의 이해

n  클래스를 사용하는 쪽(User)과 클래스 제공하는 쪽(Provider)이 있음

n  메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 됨

n  클래스가 서로를 직접 호출하지 않고 인터페이스를 매개체로 하여 접근하면 인터페이스만 맞으면 클래스가 대체되어도 문제 없음 -> 클래스 간 간접적인 관계!

 

m  디폴트 메서드와 static 메서드

n  JDK1.8부터 사용할 수 있는 기능

n  디폴트 메서드!

u  추상메서드의 기본적 구현을 제공

u  추상메서드가 아니라서 디폴트 메서드 추가해도 해당 인터페이스 구현한 클래스는 변경 없어도 됨

u  키워드 default! & 블록 { } 있어야 함

u  접근제어자 public & 생략 가능

u  조상클래스에 새로운 메서드 추가한 것!

u  이름 충돌 해결 규칙

-      여러 인터페이스의 디폴트 메서드 간의 호출 : 인터페이스 구현한 클래스에서 디폴트 메서드 오버라이딩

-      디폴트 메서드와 조상 클래스 메서드 간의 충돌 : 조상 클래스 메서드 상속, 디폴트 메서드 무시도미

 

l  내부 클래스

m  클래스 내에 선언되는 클래스

m  내부 클래스

n  두 클래스가 서로 긴밀한 관계에 있어 클래스 내에 선언된 클래스

n  내부에 선언된 클래스는 외부 클래스에서만 보통 접근하는 것!

n  장점내부클래스에서 외부 클래스 멤버들을 쉽게 접근할 수 있음코드 복잡성 줄일 수 있음(캡슐화)

m  내부 클래스 종류와 특징

n  변수 선언 위치랑 같고, 선언된 위치에 따라 구분됨

인스턴스 클래스 외부 클래스 멤버변수 선언 위치에 선언외부 클래스 인스턴스 멤버로 다뤄짐
외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언
스태틱 클래스 외부 클래스 멤버변수 선언 위치에 선언
외부 클래스의 static 멤버처럼 다뤄짐외부 클래스의 static 멤버(특히 메서드)에서 사용될 목적으로 선언
지역 클래스 외부 클래스의 메서드나 초기화블럭 안에 선언
선언된 영역 내부에서만 사용됨
익명 클래스 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)

 

m  내부 클래스의 선언

n  내부 클래스 위치는 변수 선언위치와 동일

è 선언 위치에 따라 같은 선언위치의 변수와 동일한 scope와 접근성 가짐

 

m  내부 클래스의 제어자와 접근성

n  abstract, final 제어자 사용 가능

n  private, protected 접근 제어자 사용 가능

n  static 클래스만 static 멤버 가질 수 있음(상시 사용 가능한가 문제니까)

n  final static 변수는 상수니까 모든 내부 클래스에서 정의 가능

n  인스턴스 클래스 : 외부 클래스와 인스턴스 멤버임인스턴스 변수와 static변수 모두 사용 가능

n  스태틱 클래스 : 외부 클래스의 static 멤버이므로 외부 클래스의 인스턴스 멤버 사용 불가static 멤버만 사용 가능

n  지역 클래스 : 외부 클래스 인스턴스 멤버, static 멤버 모두 사용 가능지역 클래스가 포함된 메서드에 정의된 지역 변수도 사용 가능

è but! final이 붙은 지역 변수만 접근 가능 -> 변수는 소멸해도 인스턴스는 아닐 가능성이 있어서!

n  컴파일 했을 때 파일명 : 외부클래스명$내부클래스명.class내부 클래스명 앞에 숫자 붙여서 같은 이름 내부 클래스 구분

n  this : 내부 클래스 변수와 외부 클래스 변수 명 같을 때 내부 - this, 외부 외부클래스명.this

 

l  익명 클래스

m  이름이 없는 일회용 클래스

n  클래스 선언과 객체의 생성을 동시에 하여 단 한번만 사용 가능, 하나의 객체만 생성

n  생성자 가질 수 없음(이름 없음)

n  조상 클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해 정의

è 하나의 클래스 상속과 동시에 인터페이스 구현하거나 둘 이상의 인터페이스 구현 불가능

è 즉 다중 상속 불가능

è 하나의 클래스를 상속받거나 하나의 인터페이스만 구현할 수 있음

n  컴파일 했을 때 파일명 : 익명클래스명$숫자.class

n  두 개의 독립된 클래스 작성한 다음 다시 익명클래스 이용해 변경하면 쉽다!

class EventClass{
  public static void main(String[] args){
      Button b = new Button(“start”);
      b.addActionListener(new EventHandler());  
  }          
}

class EventHandler implements ActionListener{
	public void actionPerformed (ActionEvent e){
		System.out.print(“ActionEvent!”);    
           }     
}

 

이것을!

 

class EventClass{

  public static void main(String[] args){
    Button b = new Button(“start”);
    b.addActionListener(new ActionListener(){
      public void actionPerformed (ActionEvent e){
      	System.out.print(“ActionEvent!”);   
      }
    );           
  }      
}

 

이렇게 한번에!EventHandler 라는 클래스를 만들지 않고 바로 ActionListener 인터페이스를 이용한 익명 클래스를 선언하고 생성하여 사용함

 

 

'JAVA > 이론' 카테고리의 다른 글

[java][이론]014 컬렉션 프레임웍_개괄  (0) 2020.08.28
[java][이론] 013 예외처리  (0) 2020.08.12
[java][이론] 011 다형성  (0) 2020.08.06
[java][이론] 010 제어자  (0) 2020.07.08
[java][이론] 009 package와 import  (0) 2020.07.06

01.  데이터와 데이터베이스,DBMS

m  DBMS : 데이터 베이스 관리 시스템

m  데이터와 정보

n  데이터 : 어떤 필요에 의해 수집했지만 아직 특정 목적을 위해 평가하거나 정제하지 않은 값이나 사실 또는 자료 자체

n  정보 : 수집한 데이터를 어떠한 목적을 위해 분석하거나 가공하여 가치를 추가하거나 새로운 의미를 이끌어 낼 수 있는 결과

n  가치 있는 정보를 얻으려면 조건에 맞게 데이터를 효율적으로 수집 통합하고 체계적으로 관리 분석

n  효율적인 데이터 관리를 위한 조건

u  데이터를 통합하여 관리

u  일관된 방법으로 관리

u  데이터 누락 및 중복 제거

u  여러 사용자(응용 프로그램 포함)가 공동으로 실시간 사용 가능

n  데이터베이스 : 구조화된 데이터의 집합 (위 조건 만족하면서!)

 

m  파일 시스템과 DBMS

n  파일 시스템을 통한 데이터 관리

n  서로 다른 여러 응용 프로그램이 제공하는 기능에 맞게 필요한 데이터를 각각 저장하고 관리

n  각 파일에 저장한 데이터는 서로 연관이 없고 중복 또는 누락 발생 가능

n  단층 파일 구조

 

m  DBMS를 통한 데이터 관리

n  여러 목적으로 사용할 데이터의 접근관리 등의 업무를 DBMS가 전담하는 방식

n  DBMS라는 하나의 소프트웨어가 데이터를 관리

n  응용 프로그램이 필요한 데이터작업을 DBMS에 요청하면 DBMS가 자신이 관리하는 데이터베이스로 관련 작업을 수행하고 결과값을 제공

n  작업영역의 분리

응용 프로그램의 서비스 제공과 데이터 관련 작업 효율 높임

데이터의 누락이나 중복 방지

02.  데이터 모델

m  계층형 데이터 모델

n  트리 구조 활용

n  데이터 관련성을 계층별로 나눔 -> 부모 자식 같은 관계

n  일대다(1:N) 관계의 데이터 구조를 파악해야 함

n  부모는 여러 개체 자식 가질 수 있고, 자식은 하나의 부모만 가질 수 있음

 

m  네트워크형 데이터 모델

n  망형 데이터 모델

n  그래프 구조 기반

n  개체 간 관계를 그래프 구조로 연결하므로 자식 개체가 여러 부모 개체를 가질 수 있음

 

m  객체 지향형 데이터 모델

n  객체 개념 기반으로 한 데이터 모델

n  데이터를 독립된 객체로 구성하고 관리

n  상속, 오버라이드 등 객체 지향 프로그래밍의 강력한 기능 사용할 수 있음

n  DBMS에 적용하기 힘들어서 드물다만 오라클 DBMS는 관계형 모델을 바탕으로 객체 개념 도입!

è 객체 관계형 DBMS로 영역 확장

 

m  관계형 데이터 모델

n  데이터 간 관계에 초점

n  각 데이터의 독립 특성만을 규정하여 데이터 묶음을 나눔

중복이 발생할 수 있는 데이터는 별개의 릴레이션으로 정의한 후 데이터들을 연결

n  데이터 묶음 : 개체 집합(entity set) -> table, relation

데이터 묶음 간의 관계 : 관계 (relationship)

n  관계형 데이터 모델의 핵심 구성요소

u  개체(entity) : 데이터베이스에서 데이터화하려는 사물, 개념의 정보 단위

관계형 데이터베이스의 table, relation

u  속성(attribute) : 개체를 구성하는 데이터의 가장 작은 논리적 단위

데이터의 종류∙특성∙상태 등을 정의

관계형 데이터베이스의 column

u  관계(relationship) : 개체와 개체 또는 속성 간의 연관성을 나타내기 위해 사용

관계형 데이터베이스의 외래키 관계

 

03.  관계형 데이터베이스와 SQL

m  관계형 데이터베이스

n  관계형 데이터 모델 개념을 바탕으로 데이터를 저장∙관리하는 데이터베이스

n  RDBMS (relational database management system)

n  MS_SQL, MySQL, MariaDB, PostgreSQL, DB2, Oracle 등의 DBMS가 여기에 속함

 

m  SQL

n  RDBMS 데이터베이스 질의 언어

n  구분 사용 목적에 따른 분류

u  DQL(Data Query Language) : 저장한 데이터를 원하는 방식으로 조회하는 명령어

u  DML(Data Manipulation Language) : 테이블의 데이터를 저장∙수정∙삭제하는 명령어

u  DDL(Data Definition Language) : 데이터 관리를 위해 테이블을 포함한 여러 객체를

생성∙수정∙삭제하는 명령어

u  TCL(Transaction Control Language) : 트랜잭션 데이터의 영구 저장∙취소 등과 관련된 명령어

u  DCL(Data Control Language) : 데이터 사용 권한과 관련된 명령어

 

+ Recent posts