1. Anonymous class(익명 클래스)
- 말 그대로 이름 없는 class
- Interface 사용 시 주로 익명 클래스가 사용됨 : 가독성 증가
Interface_name variable_name = new Interface_name(params...) {
@Override
// abstract method
}
2. Lambda Expression(람다식)
1) 목적
- Method는 Class 안에 존재할 수 있고 JAVA의 최소 단위는 Class이다.
- 따라서 Method를 만들기 위해 불필요한 Class 생성이 유발될 수 있다.
- 하지만 람다식을 이용하면 Class를 표현하지 않고 Method만 만들 수 있다.(Method 즉, 기능에 더 집중할 수 있다.)
- 이러한 형태의 프로그래밍을 함수형(함수기반) 프로그래밍이라 한다.
cf) 실제로 런타임 때는 Class기반(익명 클래스)로 수행됨
2) 특징
- 간결한 표현식
- 하나의 Abstract Method를 가진 Interface 생성 시 람다식이 이용 가능
- 하나의 Abstract Method만을 강제하기 위해 @FunctionalInterface 어노테이션 사용
3) 문법
// params X, return X
() -> { ... };
// params O, return X
(data_type var, ...) -> { ... };
// params X, return O
() -> { return value; };
// params O, return O
(data_type var, ...) -> { return value; };
// 생략
(var, ...) -> value; // 실행문이 return문 한 줄일 때
이 때 params의 data type을 생략할 수 있고 실행문이 return 문 한 줄이면 {, return, } 을 같이 생략할 수 있다.
4) 활용 예시
- 정렬
// 익명 클래스
Arrays.sort(list, new Compartor<String>(){
@Override
public int compare(string s1, string s2){
return s1.compareTo(s2); // 오름차순
}
});
// 람다식
Arrays.sort(list, (s1, s2) -> s1.compareTo(s2));
효율도랏;
3. Generics(제너릭스)
1) 목적
- 무엇이든 담을 수 있는 Box class를 만들고 싶다고 가정하자
- 그런데 data를 받기 위해선 JAVA가 다루는 type 개수만큼 method를 overloading해야한다.
- Object를 사용해서 다형성을 이용한다면?
원하지 않는 data type이 저장되어도 compile error가 나지 않는다. 즉, 런타임 때서야 알 수 있다.
또한 저장된 data 사용 시 형변환도 일일히 해야한다.
- 이때 제너릭스를 사용한다.
// Object
Class Box{
Object obj;
// setter & getter
}
// Generics
class Box<T>{
T obj;
// setter & getter
}
public class Testgenerics{
public static void main(...){
Box<String> b = new Box<String>();
}
}
T는 인스턴스를 생성할 때 정해주는 것으로 위의 예시에서는 String으로 정해주었다.
이를 통해 원하지 않는 data type 할당 시 compile error로 확인할 수 있고 데이터 활용 시 형 변환이 필요 없어진다.
평소 자주 사용하던 List<T>도 제너릭스를 활용한 자료구조였다.
2) Generics Interface
generics <T>에 T는 참조형만 가능하다. 따라서 기본형은 wrapper class를 사용한다.
기본형 | Wrapper class |
int | Integer |
char | Character |
나머지 | 첫문자를 대문자로 (기본형에서 Class가 되니까 라고 외우면 좋음) |
3) 와일드카드 : <?>
제너릭스를 활용한 데이터를 params로 받는 함수에 대해 overload의 번거로움을 해결할 수 있다.
List<String> list1 = ...;
List<Integer> list2 = ...;
printData(list1);
printData(list2);
public static void printData(List<?> obj){ // <?>을 안쓰면 <String>, <Integer> 2가지를 overload해야함
sysout(obj);
}
4) <? extends class_name>
특정 클래스와 해당 특정 클래스를 상속받은 클래스만 generics로 받을 수 있도록 제약하는 표현
public static void printData(List<? extends Pet> list){ // Pet과 Pet을 상속받은 클래스만 generics로 받을 수 있다
...
}
5) <? super class_name>
특정 클래스와 해당 특정 클래스의 부모 클래스만 generics로 받을 수 있도록 제약하는 표현
'CS > JAVA' 카테고리의 다른 글
[JAVA] Functional Interface, Stream, String, StringBuffer (0) | 2021.01.14 |
---|---|
[JAVA] Collection API (0) | 2021.01.14 |
[JAVA] Abstract, Interface (0) | 2021.01.12 |
[JAVA] 상속, 다형성, 캡슐화 (0) | 2021.01.12 |
[JAVA] 데이터의 메모리 할당 순서 (0) | 2021.01.12 |