
📚 인프런 강의와 스터디를 바탕으로 한 과제를 풀이한 포스트입니다.
[키워드]
익명 클래스(Anonymous Class)
이름이 없고, 주로 단일 인스턴스를 생성하고 해당 인스턴스를 사용하는 간단한 작업에 사용된다. 인터페이스를 구현하는 익명 클래스가 가장 흔하다.
익명 클래스를 사용하는 이유: 프로그램 내에서 일시적(단발성)으로 한번만 사용되어야 하는 객체일 경우 익명 클래스로 구현하는 것이 효율적이다. 일반 클래스를 사용하는 것의 장점인 '재사용성', '확장성' 측면에서 불리할 때는 익명 클래스를 이용하는 것이 합리적이며 유지 보수에 유리하다.
주요 특징
1) 이름 없음: 클래스 정의와 동시에 인스턴스를 생성한다.
2) 인터페이스 구현: 주로 인터페이스를 구현하는데 사용되며, 인터페이스를 구현함으로써 해당 인터페이스에 선언된 메서드들을 구현할 수 있다.
3) 인스턴스 생성: 클래스 정의와 함께 바로 인스턴스를 생성하는 방식이므로 단 한번의 사용을 목적으로 한다.
4) 지역적인 성격: 주로 특정 메서드 내에서 인터페이스를 구현하고 사용하는데 자주 사용되며, 이는 해당 클래스가 지역적인 성격을 가짐을 의미한다.
아래는 Spring에서 Database를 사용할 때, 사용자가 입력한 sql을 query를 이용해UserResponse 타입으로 바꿔주는 익명 클래스를 구현한 코드이다.
@GetMapping("/user")
public List<UserResponse> getUsers() {
String sql = "SELECT * FROM user";
// 유저 정보를 우리가 선언한 타입인 userResponse로 바꿔준다.
return jdbcTemplate.query(sql, new RowMapper<UserResponse>() {
@Override
public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException {
long id = rs.getLong("id");
String name = rs.getString("name");
int age = rs.getInt("age");
return new UserResponse(id, name, age);
}
});
query() 메서드로 전달된 인자로 익명 클래스를 생성한다. 이 익명 클래스는 UserResponse 타입의 RowMapper 인터페이스를 구현한다.
익명 클래스에서는 mapRow(ResultSet rs, int rowNum)을 오버라이드한다. 메서드에서의 ResultSet 객체에는 결과가 담겨있다. 이 객체에 getType("필드이름") 을 사용해서
실제 값을 가져온다.
id, name, age를 받는 UserResponse의 생성자를 만든다.
람다
앞에서의 익명 클래스를 람다식으로 바꾸면 다음과 같다.
@GetMapping("/user")
public List<UserResponse> gerUser() {
String sql = "SELECT * FROM user";
// 유저 정보를 우리가 선언한 타입인 userResponse로 바꿔준다.
return jdbcTemplate.query(sql, (rs, rowNum) -> {
long id = rs.getLong("id");
String name = rs.getString("name");
int age = rs.getInt("age");
return new UserResponse(id, name, age);
});
}
함수형 프로그래밍
스트림 API
@FunctionalInterface
@FunctionalInterface 어노테이션을 사용한다. 해당 인터페이스가 함수형 인터페이스 조건에 맞는지 검사해준다.주요 함수형 인터페이스
- Predicate: 인자 하나를 받아서 boolean 타입 리턴.
- Consumer: 인자 하나를 받고 아무것도 리턴하지 않음.
- Supplier: 인자를 받지 않고 T 타입의 객체 리턴.
- Function: T 타입 인자를 받아서 R 타입 리턴.
- Comparator: T 타입 인자 두 개를 받아서 int 타입 리턴.
- Runnable: 객체를 받지 않고 리턴도 하지 않음. 이름 그대로 실행만 할 수 있음.
- Callable: 객체를 받지 않고 T 타입 객체를 리턴.
메소드 참조(method reference)
(base, exponent) -> Math.pow(base, exponent); 다음과 같은 람다식을Math::pow; 메소드 참조를 사용하면 이렇게 작성할 수 있다.[질문]
자바의 람다식은 왜 등장했을까?
람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?
[Reference]