[Java] 열거형, 제네릭, 예외 처리

·2022년 9월 14일
0

Java

목록 보기
7/14
post-thumbnail

컬렉션(Collection)

열거형(Enum)

열거형

열거형이란?

  • 서로 연관된 상수들의 집합
  • 몇가지로 한정된 변하지 않는 데이터를 다루는데 사용

열거형의 장점

  1. 여러 상수들을 보다 편리하게 선언 및 관리 할 수 있다.
  2. 상수명의 중복을 피할 수 있다.
  3. 타입에 대한 안정성을 보장
  4. 간결하고 가독성이 좋은 코드를 작성할 수 있다.
  5. switch문 사용 가능

    💡 switch문은 변수의 기본형 8가지와 열거형 enum타입만 사용할 수 있어 상수를 사용자 타입으로 정의하기 보다 열거형으로 정의하는 것이 좋다.

열거형의 사용

열거형 선언

enum 열거형이름 {
	상수명1,    // 정수값 0 할당
    상수명2,    // 정수값 1 할당
    상수명3,    // 정수값 2 할당
    ...
    }
  • 상수의 값을 지정하지 않아도 자동적으로 0부터 시작하는 정수값이 할당된다.

열거형 사용

열거형이름.상수명

💡 클래스 변수인 static 변수를 참조할 때 클래스이름.변수명으로 했던 것과 같다.4

열거형 메서드

  • 모든 열거형의 조상인 (java.lang.Enum)에 정의되어 있는 것

제네릭(Generic)

제네릭

제네릭이란?

  • Generic : 일반적인
  • 타입을 지정하는 것이 아니라, 추후에 지정할 수 있도록 일반화해두는 것
  • 작성한 클래스 또는 메서드의 코드가 특정 데이터 타입에 얽매이지 않게 해둔 것

제네릭의 장점

  • 하나의 클래스만으로도 모든 타입의 데이터를 저장할 수 있는 인스턴스 생성 가능

예제 코드

  • 제네릭 미사용
class Basket {
    private String item;

    Basket(String item) {
        this.item = item;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }
}

Basket<String> basket1 = new Basket<String>("어쩌고");
Basket<Integer> basket1 = new Basket<Integer>(123);  // 에러 발생!!
  • 제네릭 사용
class Basket<T> {
    private T item;

    public Basket(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }

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

Basket<String> basket1 = new Basket<String>("어쩌고");
Basket<Integer> basket1 = new Basket<Integer>(123); 

💡 클래스 이름 옆에 T 를 추가하고, 클래스 내부에 변경할 변수들의 타입을 T로 바꿔 사용. -> 클래스 내의 T를 다 뫄뫄로 바꿔라.
T : 타입 매개변수라고 한다.

래퍼 클래스(wrapper class)

  • 8개의 기본 타입에 해당하는 데이터를 객체로 표현하기 위해 포장해주는 클래스
  • 각각의 타입에 해당하는 데이터를 인수로 전달 받아 해당 값을 가지는 객체로 만들어 준다.
  • 예시) Integer : int 타입의 래퍼 클래스
  • 래퍼 클래스로 감싸고 있는 기본 타입 값은 외부에서 변경 불가하며, 변경하려면 새로운 포장 객체를 만들어야 한다.

    💡 기본 타입의 객체화! (풀네임! 앞글자만 대문자 사용!)

제네릭 클래스

제네릭 클래스

  • 제네릭이 사용된 클래스
  • 타입 매개변수는 여러 개 사용될 수 있다.
  • 타입 매개변수 : T - Type, K - Key, V - Value가 자주 사용된다.

제네릭 클래스를 정의할 때 주의할 점

  • 클래스 변수(static + 인스턴스 변수)에는 타입 매개변수를 사용할 수 없다.
    -> 이유 : 클래스 변수는 공통적인 변수인데 타입에 변화를 주면 인스턴스 별로 값이 달라지기 때문에 공유가 불가능

제네릭 클래스의 사용

  • 타입 매개변수에 치환될 타입으로 기본형의 타입(int, double 등)을 지정할 수 없음 -> 래퍼 클래스를 사용하여 함
클래스명<변환할타입> 인스턴스명 = new 클래스명<변환할타입(생략가능)>();
  • 다형성 적용 가능

제한된 제네릭 클래스

  • 제네릭 클래스는 인스턴스화를 할 때, 어떠한 타입으로도 지정이 가능하다.
    -> 타입을 지정하는데 제한이 없다.
  • 제네릭 클래스의 타입 매개 변수를 제한 두는 법
    <T extends A클래스> : A클래스의 하위 클래스로만 인스턴스화 가능

제네릭 메서드

  • 클래스 내부의 특정 메서드에만 제네릭 선언
class Basket {
		...
		public <T> void add(T element) {
				...
		}
}
  • 반환타입 앞에서 타입 매개변수 선언을 한다.

  • 제네릭 메서드의 타입 매개변수는 제네릭 클래스의 타입 매개변수는 별개의 것.
    이름이 동일하더라도 다른 타입 매개변수로 간주된다.

    💡 클래스 : 클래스에서 선언된 타입 매개변수는 클래스가 인스턴스화 될 때 타입이 지정
    메서드 : 메서드가 호출될 때 타입이 지정

  • 제네릭 메서드 호출

클래스A<String> a = new 클래스A<>();     // 인스턴스 생성
a.<Integer>add(10);                    // 메서드 호출
a.add(10);                             // 타입 지정 생략 가능
  • 클래스와 달리 클래스 메서드에도 제네릭을 선언할 수 있다.
	static <T> int price (T element) {}

💡 제네릭 메서드는 메서드 호출 시, 타입이 결정되므로 String 클래스와 같은 타입이 지정되어야 사용 가능한 메서드는 사용이 불가능하다.
❗ 클래스의 최상위 클래스인 Object 클래스의 메서드는 사용이 가능하다.

와일드 카드

와일드 카드란?

  • 어떠한 타입으로든 대체될 수 있는 타입 파라미터
1. <? extends T> : 상한 제한, TT를 상속받는 하위클래스만 타입으로 지정
2. <? super T> : 하한 제한, TT의 상위클래스만 타입으로 지정
3. <?> = <? extends Object> : 모든 클래스를 타입으로 지정 

예외 처리(Exception Handling)

예외 처리란?

  • 예기치 않게 발생하는 에러에 대응할 수 있는 코드를 사전에 작성하는 것

에외처리의 장점

  1. 에러로 인해 프로그램이 비정상적으로 종료되는 것을 방지
  2. 정상적인 실행 상태를 유치

에러

에러(Error)와 예외(Exception)

  • 코드 실행(런타임)시 잠재적으로 발생할 수 있는 프로그램 오류
    1. 에러 : 복구가 어려운 수준의 심각한 오류(하드웨어 문제인 경우가 다수)
    2. 예외 : 잘못된 사용, 코딩으로 인한 상대적으로 미약한 수준의 오류
      이 경우에는 코드 수정 등을 통해 수습이 가능하다.

컴파일 에러

  • 컴파일 시 발생하는 에러
  • 컴파일러가 자동적으로 오류를 감지하여 표시해준다.
  • 세미콜론 생략, 오탈자 등 문법적인 문제(신택스(syntax))
java: ')' expected

런타임 에러

  • 코드를 실행한, 런타임 시에 발생하는 에러
  • 컴파일러가 인식하지 못하는 에러로 런타임 시에만 에러를 확인할 수 있다.
public class RuntimeErrorTest {

    public static void main(String[] args) {
        System.out.println(4 * 4);
        System.out.println(4 / 0); // 예외 발생
    }
}

//출력값
16
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at RuntimeErrorTest.main(RuntimeErrorTest.java:5)

예외 클래스

상속 계층도

try-catch문

try {
    // 예외가 발생할 가능성이 있는 코드를 삽입
} 
catch (ExceptionType1 e1) {
    // ExceptionType1 유형의 예외 발생 시 실행할 코드
} 
catch (ExceptionType2 e2) {
    // ExceptionType2 유형의 예외 발생 시 실행할 코드
} 
finally {
    // finally 블럭은 옵셔널
    // 예외 발생 여부와 상관없이 항상 실행
}

예외 전가

예외전가 : throws

  • 메서드 선언부 끝에 throws키워드와 예외들을 나열하면 된다.
반환타입 메서드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
	...생략...
}

예외 의도적으로 발생시키기: throw

  • throw 키워드를 사용하여 의도적으로 예외를 만드는 방법
throw 예외클래스;
profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게

0개의 댓글