열거형은 여러 상수들을 보다 편리하게 선언할 수 있도록 만들어진 자바의 문법요소이며, 몇 가지로 한정된 변하지 않는 데이터를 다루는데 사용한다.
enum
을 사용하면 코드를 단순하고 가독성이 좋게 만들 수 있다는 장점이 있다. 또한 enum
으로 정의한 상수는 switch
문에서도 사용이 가능하다.
여러 상수들을 보다 편리하게 선언하고 관리할 수 있게하며, 상수명의 중복을 피하고, 타입에 대한 안정성을 보장한다.
enum 열거형이름 { 상수명1, 상수명2, 상수명3, ...}
enum Seasons { SPRING, SUMMER, FALL, WINTER }
enum Frameworks { DJANGO, SPRING, NEST, EXPRESS }
상수는 대소문자로 모두 작성이 가능하지만 관례적으로 대문자로 작성한다.
각각의 상수들에는 따로 값을 지정해주지 않아도 자동적으로 0부터 시작하는 정수값이 할당되어 각각의 상수를 가리키게 된다.
열거형에 사용하는 메서드
리턴 타입 | 메소드 (매개변수) | 설명 |
---|---|---|
String | name() | 열거 객체가 가지고 있는 문자열을 리턴하며, 리턴되는 문자열은 열거타입을 정의할 때 사용한 상수 이름과 동일하다. |
int | ordinal() | 열거 객체의 순번(0부터 시작)을 리턴한다. |
int | compareTo(비교값) | 주어진 매개값과 비교해서 순번 차이를 리턴한다. |
열거 타입 | valueOf(String name) | 주어진 문자열의 열거 객체를 리턴한다. |
열거 배열 | values() | 모든 열거 객체들을 배열로 리턴한다. |
제네릭은 타입을 구체적으로 지정하는 것이 아니라, 추후에 지정할 수 있도록 일반화해두는 것을 의미한다. 즉, 작성한 클래스 또는 메서드의 코드가 특정 데이터 타입에 얽매이지 않게 해둔 것을 의미한다.
제네릭을 사용하면 단 하나의 클래스만으로 모든 타입의 데이터를 저장할 수 있는 인스턴스를 만들 수 있다.
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;
}
}
T
를 타입 매개변수라고 한다. Basket<String> basket1 = new Basket<String>("기타줄");
T
값이 모두 String
으로 간주된다. 제네릭 클래스
라고 하며, 위에서 사용된 Basket
클래스가 제네릭 클래스이다.타입매개변수 여러개 사용시
class Basket<K, V> { ... }
class Basket<T> {
private T item1; // O
static T item2; // X
}
static
이 붙은 변수 또는 메서드에는 타입 매개변수를 사용할 수 없다.Cake<String> cake1 = new Cake<>("bread");
new Cake<…>은 아래와 같이 구체적인 타입을 생략하고 작성해도 된다. (참조변수의 타입으로부터 유추 가능)
타입 매개변수를 선언할 때 아래와 같이 코드를 작성해주면 Basket
클래스를 인스턴스화할 때 타입으로 Flower
클래스의 하위 클래스만 지정하도록 제한된다.
class Flower { ... }
class Rose extends Flower { ... }
class RosePasta { ... }
class Basket<T extends Flower> {
private T item;
...
}
public static void main(String[] args) {
// 인스턴스화
Basket<Rose> roseBasket = new Basket<>();
Basket<RosePasta> rosePastaBasket = new Basket<>(); // 에러
}
&
를 사용한다.interface Plant { ... }
class Flower implements Plant { ... }
class Rose extends Flower implements Plant { ... }
class Basket<T extends Flower & Plant> { // (1)
private T item;
...
}
public static void main(String[] args) {
// 인스턴스화
Basket<Flower> flowerBasket = new Basket<>();
Basket<Rose> roseBasket = new Basket<>();
}
클래스 내부의 특정 메서드만 제네릭으로 선언할 수 있으며, 제네릭 메서드라고 한다.
제네릭 메서드의 타입 매개변수 선언은 반환타입 앞에서 이루어지며, 해당 메서드 내에서만 선언한 타입 매개변수를 사용할 수 있다.
class Basket {
...
public <T> void add(T element) {
...
}
}
T
라는 타입 매개변수명을 사용한다 하더라도, 같은 알파벳 문자를 이름으로 사용하는 것일 뿐, 서로 다른 타입 매개변수로 간주된다.class Basket<T> { // 1 : 여기에서 선언한 타입 매개변수 T와
...
public <T> void add(T element) { // 2 : 여기에서 선언한 타입 매개변수 T는 서로 다름
...
}
}
Basket<String> basket = new Bakset<>(); // 위 예제의 1의 T가 String으로 지정됨
basket.<Integer>add(10); // 위 예제의 2의 T가 Integer로 지정됨
basket.add(10); // 타입 지정을 생략 가능
class Basket {
...
static <T> int setPrice(T element) {
...
}
}
length()
와 같은 String
클래스의 메서드는 제네릭 메서드를 정의하는 시점에 사용할 수 없다.class Basket {
public <T> void print(T item) {
System.out.println(item.length()); // 불가
}
}
Object
클래스의 메서드는 사용이 가능하다. 모든 클래스는 Object 클래스를 상속받기 때문이다. equals()
, toString()
등이 포함된다. class Basket {
public <T> void getPrint(T item) {
System.out.println(item.equals("Kim coding")); // 가능
}
}
와일드카드는 어떠한 타입으로든 대체될 수 있는 타입 파라미터를 의미하며, 기호 ?
로 와일드카드를 사용할 수 있다.
일반적으로 와일드카드는 extends
와 super
키워드를 조합하여 사용한다.
<? extends T>
<? super T>
<? extends T>
는 와일드카드에 상한 제한을 두는 것으로서, T와 T를 상속받는 하위 클래스 타입만 타입 파라미터로 받을 수 있도록 지정한다.
<? super T>
는 와일드카드에 하한 제한을 두는 것으로, T와 T의 상위 클래스만 타입 파라미터로 받도록 한다.
extends
및 super
키워드와 조합하지 않은 와일드카드<?>
는 <? extends Object>
와 같다.
컴파일 에러는 이름 그대로 “컴파일 할 때" 발생하는 에러를 가리킨다.
주로 세미콜론 생략, 오탈자, 잘못된 자료형, 잘못된 포맷 등 문법적인 문제를 가리키는 신택스(syntax) 오류로부터 발생하기 때문에 신택스 에러(Systax Errors) 라고 부르기도 한다.
런타임 에러는 코드를 실행하는 과정, 즉 런타임 시에 발생하는 에러를 가리킨다. 즉, 프로그램이 실행될 때 만나게되는 에러다.
컴파일 에러가 주로 문법 요소와 관련한 신택스(syntax) 에러였다면 런타임 에러는 주로 개발자가 컴퓨터가 수행할 수 없는 특정한 작업을 요청할 때 발생한다.
Throwable
클래스로부터 확장되며, 모든 예외의 최고 상위클래스는 Exception
클래스다. 런타임 시 발생하는 RuntimeException
클래스와 그 하위 클래스를 제외한 모든 Exception 클래스와 그 하위 클래스들을 가리킨다.
컴파일러가 코드 실행 전에 예외 처리 코드 여부를 검사한다고하여 checked 예외
라 부르기도 한다.
주로 잘못된 클래스명(ClassNotFoundException)이나 데이터 형식(DataFormatException) 등 사용자편의 실수로 발생하는 경우가 많다.
런타임 시 발생하는 RuntimeException
클래스와 그 하위클래스를 말한다.
컴파일러가 예외 처리 코드 여부를 검사하지 않는다는 의미에서 unchecked 예외
라 부르기도 한다.
주로 개발자의 실수에 의해 발생하는 경우가 많고, 자바 문법 요소와 관련이 있다.
try {
// 예외가 발생할 가능성이 있는 코드를 삽입
}
catch (ExceptionType1 e1) {
// ExceptionType1 유형의 예외 발생 시 실행할 코드
}
catch (ExceptionType2 e2) {
// ExceptionType2 유형의 예외 발생 시 실행할 코드
}
finally {
// finally 블럭은 옵셔널
// but, 포함되는 경우에는 예외 발생 여부와 상관없이 항상 실행
}
e.getMessage() : 에러의 원인을 간단하게 출력한다.
e.toString() : 에러의 Exception 내용과 원인을 출력한다.
e.printStackTrace() : 에러의 발생근원지를 찾아서 단계별로 에러를 출력한다.
throws
키워드와 발생할 수 있는 예외들을 쉽표로 구분하여 나열해주면 된다.반환타입 메서드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
...생략...
}
void ExampleMethod() throws Exception {
}
throw
키워드를 사용하면 의도적으로 예외를 발생시킬 수 있다.public class ExceptionTest {
public static void main(String[] args) {
try {
Exception intendedException = new Exception("의도된 예외 만들기");
throw intendedException;
} catch (Exception e) {
System.out.println("고의로 예외 발생시키기 성공!");
}
}
}