✎NHN Academy | JAVA

NHN Academy - 2024.08.29(Thu)

박순돌 2024. 8. 29. 17:34
 

Module 11: Generics

시작문제 - 스택.java (배열 사용)

클래스이름<T> = T는 타입(EX> String, int, char...)  →  배열은 T[]

 

서브타입 다형성  :  Subtyping Polymorphism  →  Method Overriding

임시 다형성  :  Ad-hoc Polymorphism  →  Method Overloading

파라미터화한 다형성  :  Parametric Polymorphism  →  Gemerics

 

 

공변성 - Covariant : 타입생성자에게 리스코프 치환 법칙을 허용해, 유연한 설계를 가능(공통적으로 변경될 수 있다)

                               : A가 B의 상위 타입이고, T<A>가 T<B>의 상위 타입이면 공변

                               : java에서는 extends 키워드를 사용해 공변 처리

 

반공변성 - Contravariant : 공변성의 반대 개념으로 자기 자신과 부모 객체만을 허용

                                         : A가 B의 상위 타입이고, T<A>가 T<B>의 하위 타입이면 반공변

                                         : java에서는 super 키워드를 사용해 반공변 처리

 

  • Generics는 타입 안정성(Type Safety)를 지원 : 타입 파라미터를 통해 전달된 타입 정보를 이용하여 컴파일 타임에 검사
  • java.lang.Object 타입으로 변환되는 객체 형 변환은 런타임에 검사됨 : 컴파일시에 오류를 발견할 수 없음(java.lang.ClassCastException 예외 발생)
  • Generics는 타입이 명확히 명시되므로 컴파일 타임에 오류를 검출할 수 있음

메소드에 타입 파라미터를 선언 가능 O : 불필요한 타입 캐스팅 할 필요 없음  /  효율성 증가

Generic 타입 선언

 - 일반 타입 선언(클래스와 인터페이스)에 타입 파라미터를 추가한 형태로 사용

 - 타입 파라미터는 클래스나 인터페이스의 이름뒤에 선언하며, < > 기호 사이에 열거됨

 - 하나 이상의 타입 파라미터를 사용할 수 있음

 

정렬되어 있는 자료구조 = B-Tree                  |                   정렬되지 않은 자료구조 = Heap

각각은 뭐가 더 빠를까?          Scan , Range , Equality

HashTable = key와 value에 null을 허용 X   /   동기화를 보장 O  →  BUT, 사용 X

HashMap = key와 value에 null을 허용 O   /   동기화를 보장 X

Box<Integer, String> box = new Box<Integer, String>(1, "num");     // 2개의 타입 작성 O

Box<Integer, String> box = new Box<>(1, "num");     // <> 사이 생략 O

 

// Student.java

public class Student implements Comparable<Student> {
    int no;
    String name;
    String phoneNumber;

    public Student(int no, String name, String phoneNumber) {
        this.no = no;
        this.name = name;
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return this.no + ", " + this.name + ", " + this.phoneNumber;
    }
    
    public int compareTo(Student s) {
        // return this.no - no;
        if(this.no > s.no) {
            return 1;
        }
        else if(this.no == s.no) {
            return 0;
        }
        else {
            return -1;
        }
    }
}

 

// Test.java

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Test {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student(3, "Celine", "010-1111-2222"));
        list.add(new Student(1, "James", "010-2222-3333"));
        list.add(new Student(2, "Jason", "010-4444-3333"));

        for(Student s : list) {
            System.out.println(s);
        }

        Collections.sort(list);

        for(Student s : list) {
            System.out.println(s);
        }
    }
}

List<Student> list = new ArrayList<Student>();  ←  <> 속의 Student는 왼쪽에만 작성해도 O

 

 

와일드 카드

    - 파라미터나 return 값이 특정한 타입 파라미터를 정의하지 않고 임의의 타입을 지정

    - 타입 인자에 대한 제한을 두지 않음

    - 특정 타입 또는 상속 받은 타입으로 타입 인자를 제한

    - 특정 타입 또는 상위 타입으로 타입 인자를 제한

무제한 와일드 카드

    - 타입 인자에 제한을 두지 않음

슈퍼 타입 제한 와일드 카드

    - 지정된 타입이나 그로부터 상속 받은 타입에 한해서만 적용

    - 타입 파라미터에 extends 키워드를 사용해 허용가능한 최상위 타입을 선언

서브 타입 제한 와일드 카드

    - 지정된 타입이나 슈퍼 타입에 한해서만 적용

    - 타입 파라미터에 super 키워드를 사용해 허용 가능한 최하위 타입을 선언

 

 

 

Generic에서의 타입 삭제

    - Generic 타입 파라미터는 컴파일시에 모두 삭제됨

    - 타입 파라미터가 제한되지 않는 경우, Object 타입으로 변경됨

    - 타입 제한이 있는 경우, 해당 타입으로 변경됨

 

 

 

타입 파라미터 제약

    - 타입 파라미터 인자로 기본 데이터 타입을 사용할 수 없음  :  컴파일 과정에서 타입 파라미터 정보는 모두 삭제, Object 타입으로 처리

    - 타입 파라미터 변수의 객체를 생성할 수 없음  :  타입 파라미터는 타입의 인자가 주어지지 전까지는 생성할 수 없음

    - static 필드로 선언할 수 없음  :  타입 파라미터 인자가 달라질 수 있어 특정 타입으로 생성할 수 없음

타입 파라미터 명명 권장 사항

    - E : 요소 (Element - Java Collections Framework에서 폭 넓게 사용됨)

    - K : 키 (Key)

    - N : 숫자 (Number)

    - T : 타입 (Type)

    - V : 값 (Value)

    - S, U, V 등 : 2번째, 3번째, 4번째 등

 

 

 

Generic 타입 제약

    - Generic 타입은 타입 변환 될 수 없으며, instanceof 연산자를 사용할 수 없음

         : 타입 파라미터는 모두 컴파일시 Object로 치환됨

         : 컴파일러에서 타입 변환은 참조 타입의 경우 상속 관계만 확인

         : 타입 파라미터가 Object 타입으로 치환되어 instanceof로 구분이 어려움

    - Generic 타입의 배열은 생성할 수 없음

         : Java의 배열은 공변적이지만 Generic 타입은 불공변적

         : Java의 배열은 타입 안전을 보장할 수 없음

    - Exception 타입의 서브 타입이 될 수 없음

         : Generic 클래스는 Throwable 클래스를 직접적 또는 간접적으로 확장할 수 없음

 

 

 

메소드 오버로딩 제약

  - 타입 파라미터만 다른 동일한 시그너처의 메소드는 존재할 수 없음  :  타입 파라미터는 모두 컴파일시 Object로 치환됨

 

 

추상 메소드 = 구현이 없는 메소드 (인터페이스에는 추상 메소드가 꼭 존재해야 O

 

1. 클래스 구현   2. 익명 클래스   3. 람다 식   4. 메소드 참조

 

Functional Interface  :  단 하나의 abstract method를 가지고 있는 인터페이스    ←   이 조건을 갖추면 자격 O

                                    :  SAM(Single Abstract Method) 인터페이스 라고도 부름

                                    :  Java에서 함수를 객체처럼 다룰 수 O

                                         ←   변수에 할당(Assignment), 다른 함수의 인자(Argument)로 전달, 다른 함수의 결과로서 return O

 

Anomymous Method  단 한번만 사용할 수 있고, 하나의 객체만을 생성할 수 있는 일회용 클래스

Lambda Expression  :  Java 8에서 추가된, 파라미터를 받아 짧은 코드 블록을 수행하고 필요에 따라 값을 return하는 표현 방법

                                    :  메소드와 유사하지만 이름은 X

                                    :  표현식에 사용할 수 있는 모든 곳에서 구현 가능

                                    :  default 메소드와 static 메소드가 포함된 함수형 인터페이스는 람다 식을 사용하여 사용

 

Lambda Expression 형식

 

파라미터 목록과 표현 식의 블록으로 선언  :  (int i, int j, ...) -> (int x = i + j; ...)

파라미터 타입은 생략 가능  :  (a, b, …) -> { int x = a + b; … }

파라미터가 하나인 경우, 괄호 생략 가능  :  a -> { int x = a + b; … }

수행문이 하나이고, 지역 변수 선언 또는 return이 없는 경우 { } 생략 가능  :  (Task task) -> task.run()

괄호가 생략된 수행문에 return 키워드가 포함되어 있을 경우 return 생략 가능  :  (a, b) -> a + b

가장 단순한 형태  :  x -> x

 

 

메소드 참조

  - Lambda Expression을 단순하게 만들어주는 구문

  - Lambda Expression이 단 하나의 메소드만을 호출하는 경우에 사용

  - 해당 Lambda Expression에서 불필요한 parameter를 제거하고 사용할 수 있음

  - 불필요한 parameter를 제거하고 :: 기호를 사용하여 표현

 

 

iterator() : hasNext(), Next() 둘다 읽을 수 O + foreach문도 읽을 수 O

 

1. 학생 : 상속

2. 군집

3. 군집을 열거형으로 Iterator (Collections.sort)

4. 정렬 가능 O

5. 다양한 방법으로 정렬


왼쪽 사진) 오류 전체 코드 : $ java TypeSafetyExample Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') at TypeSafetyExample.main(TypeSafetyExample.java:16)


 

'✎NHN Academy | JAVA' 카테고리의 다른 글

NHN Academy - 2024.09.02(Mon)  (0) 2024.09.02
NHN Academy - 2024.08.30(Fri)  (0) 2024.08.30
NHN Academy - 2024.08.28(Wed)  (1) 2024.08.28
NHN Academy - 2024.08.27(Tue)  (0) 2024.08.27
NHN Academy - 2024.08.26(Mon)  (0) 2024.08.26