Enumerated type
서로 연관된 상수들의 집합
상수란 변하지 않는 값을 의미하며, final
키워드를 통해 선언가능.
열거형을 사용하면 아래의 3가지 문제에 대해 자유로움.
⠀⠀⠀⠀
열거형을 사용하지 않고 상수를 선언하는 경우
public static final int
를 이용하여 정수 값을 할당할 때, 같은 상수명을 사용할 경우 컴파일 에러발생.==
연산자를 사용하면 의미적으로 다른 개념을 가지는 경우에도 에러가 발생하지 않음.byte, short, int, long, float, double, char, boolean
char, byte, short, int, Character, Byte, Short, Integer, String, enum
⠀⠀⠀⠀
0, 1, 2, ...
의 정수값이 할당되어 각각의 상수값을 지칭함.Meal
열거형은 3개의 열거 객체를 포함하고 있음.열거형이름.상수명
을 통해서 열거형으로 선언된 상수에 접근 가능.enum 열거형이름 { 상수명1, 상수명2, 상수형3, ...} enum Meal { BREAKFAST, LUNCH, DINNER } ⠀⠀⠀⠀ enum Meal { BREAKFAST, // 정수값 0 할당 LUNCH, // 정수값 1 할당 DINNER // 정수값 2 할당 }
enum Meal { BREAKFAST, // 0 LUNCH, // 1 DINNER // 2 } ⠀⠀⠀ public class Main { public static void main(String[] args) { Meal meal = Meal.DINNER; ⠀⠀⠀ switch(meal) { case BREAKFAST: System.out.println("아침"); break; case LUNCH: System.out.println("점심"); break; case DINNER: System.out.println("저녁"); break; } } } // 출력 // DINNER
java.lang.Enum
에 정의되어 있음.
리턴타입 메소드(매개변수) 기능 String name() 열거객체가 가지고 있는 문자열 리턴 int ordianl() 열거객체의 순번 리턴 int compareTo(비교값) 매개값과의 순번 차이 리턴 열거타입 valueOf(String name) 문자열의 열거객체 리턴 열거배열 values() 모든 열거 객체를 배열로 리턴 enum Meal { BREAKFAST, LUNCH, DINNER } ⠀⠀⠀ public class EnumTest { public static void main(String[] args) { Meal meal = Meal.LUNCH; Meal[] allMeal = Meal.values(); // 모든 열거 객체 배열로 리턴 for(Meal m : allMeal) { System.out.printf("%s=%d%n", m.name(), m.ordinal()); } // 열거 객체가 가지고 있는 문자열 리턴 + 순번 리턴 ⠀⠀⠀ System.out.println(meal.compareTo(Meal.DINNER)); Meal findMeal = Meal.valueOf("DINNER"); System.out.println(findMeal); System.out.println(meal == Meal.valueOf("LUNCH")); } // 문자열의 열거객체 리턴 } // 출력 // BREAKFAST=0 // LUNCH=1 // DINNER=2 // -1 ( 2 - 3 = -1) // DINNER // true
Annotation
다른 프로그램에게 유용한 정보를 제공하기 위해 만들어진 수단
에너테이션의 역할
표준 애너테이션 ⠀자바에서 기본적으로 제공
@SuppressWarnings
뒤에 괄호를 붙이고 억제하고 싶은 경고메세지를 지정할 수 있음.// 경고 메세지의 종류 @SuppressWarings(”message”) ”all” 모든 경고를 억제 ”deprecation” Deprecated 메서드를 사용한 경우 나오는 경고 억제 ”fallthrough” switch문에서 break 구문이 없을 때 경고 억제 ”finally” finally 관련 경고 억제 ”null” null 관련 경고 억제 ”unchecked” 검증되지 않은 연산자 관련 경고 억제 ”unused” 사용하지 않는 코드 관련 경고 억제
@SuppressWarnings({"unused", "null"})
@FunctionalInterface public interface Runnable { public abstract void run (); } // 하나의 추상 메서드
메타 애너테이션 ⠀에너테이션을 정의하는 데 사용. 애너테이션에 붙임.
java.lang.annotation.ElementType
에 정의되어 있음.@Override
와 @SuppressWarnings
를 제외하고 모두 @Documented
적용되어 있음.@Documented @Target(ElementType.Type) public @interface CustomAnnotation { }
@Inherited
애너테이션을 상위 클래스에 붙이면, 하위 클래스에도 상위 클래스의 애너테이션이 동일하게 적용됨.@Inherited // @SuperAnnotation이 하위 클래스까지 적용 @interface SuperAnnotation{ } ⠀ @SuperAnnotation class Super { } ⠀ class Sub extends Super{ } // Sub에 애너테이션 적용
유지 정책 설명 SOURCE 소스파일에 존재, 클래스 파일에는 존재 X CLASS 클래스 파일에 존재, 실행시 사용 X, 기본값 RUNTIME 클래스 파일에 존재, 실행시 사용 O @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) //오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도 //클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐 public @interface Override(){ }
사용자 정의 애너테이션 ⠀사용자가 직접 에너테이션을 정의해서 사용.
java.lang.annotation
인터페이스를 상속받기 때문에 다른 클래스나 인터페이스를 상속 받을 수 없음.@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙여 애너테이션을 정의 타입 요소명(); // 애너테이션 요소를 선언 }
Lambda
함수형 프로그래밍을 지원하는 자바의 문법 요소
식(expression)을 표현한 것으로, 코드를 매우 간결하고 명확하게 표현함.
⠀
람다식의 기본 문법
// 일반적인 메서드의 형태 int sum(int num1, int num2) { return num1 + num2; } ⠀ // 반환타입과 메서드명 제거 + 화살표 추가 (int num1, int num2) -> { return num1 + num2; } ⠀ // 반환값이 있는 경우에는 return과 세미콜론 생략 가능 (int num1, int num2) -> { num1 + num2 }
// (1) 실행문이 하나인 경우는 중괄호 생략 가능 (int num1, int num2) -> num1 + num2 ⠀⠀ // (2) 매개변수 타입을 쉽게 유추할 수 있는 경우, 매개변수 타입 생략 가능 (num1, num2) -> num1 + num2
함수형 인터페이스
람다식은 객체이다. 이름이 없는 익명 클래스의 형태.
Object
클래스에는 sum
메서드가 없기 때문에, 참조변수에 담아도 메서드를 사용할 수 없음.public class LamdaExample1 { public static void main(String[] args) { Object obj = new Object() { int sum(int num1, int num2) { return num1 + num1; } }; } // 람다식 Object obj = (num1, num2) -> num1 + num2 로 대체 가능
public class Main { public static void main(String[] args) { LambdaEx l = (num1, num2) -> num1 + num2 ⠀⠀ System.out.println(l.sum(10,15)) } @FunctionalInterface // 함수형 인터페이스가 바르게 정의되었는 지 확인하는 애너테이션 interface LambdaEx { public abstract int sum(int num1, int num2); }
@FunctionalInterface public interface L1 { public void play(); } // 아래와 같은 형태로 람다식을 작성해야 함. L1 example = () -> { ... }; // example.play(); 로 play() 호출.
public class Main { public static void main(String[] args) throws Exception { L1 example; example = () -> { String str = "첫 번째 메서드"; System.out.println(str); }; example.play(); ⠀⠀ example = () -> System.out.println("두 번째 메서드"); //실행문이 하나라면 중괄호 { }는 생략 가능 example.play(); } } // 출력값 첫 번째 메서드 두 번째 메서드
@FunctionalInterface public interface L2 { public void play(int x); }
public class Main { public static void main(String[] args) throws Exception { L2 example; example = (x) -> { int result = x + 3; System.out.println(result); }; example.play(2); ⠀⠀ example = (x) -> System.out.println(x * 5); example.play(3); } } // 출력값 5 15
@FunctionalInterface public interface L3 { public play(int x, int y); }
public class Main { public static void main(String[] args) throws Exception { L3 example; example = (x, y) -> { int result = x + y; return result; }; int result1 = example.play(6, 3); System.out.println(result1); // 9 ⠀⠀ example = (x, y) -> { return x - y; }; int result2 = example.play(7, 4); System.out.println(result2); // 3 ⠀⠀ example = (x, y) -> x * y; // 실행문이 한 줄인 경우, 중괄호와 return문 생략 int result3 = example.play(9, 1); System.out.println(result3); // 9
메서드 레퍼런스
불필요한 매개변수를 제거할 때 사용.
메서드 참조 ::
// 단순히 메서드를 참조하는 경우, 람다식을 메서드 참조로 대치 // 정적(static) 메서드 참조 클래스명 :: 메서드 // 인스턴스 메서드 참조 ( 객체 생성 후 참조 가능) 참조 변수 :: 메서드
생성자 참조 ::
// 단순히 객체를 생성하고 리턴하는 경우, 람다식을 생성자 참조로 대치 (a,b) -> {return new 클래스(a,b);}; // 생성자 참조 클래스명 :: new