자바 8부터 도입된 기능으로, 익명 함수를 더 간단하게 표현할 수 있게 해줍니다. 람다 표현식은 일회성으로 사용할 작은 함수가 필요할 때 주로 활용됩니다. 자바에서는 함수형 프로그래밍을 가능하게 해주는
람다 표현식은 메서드를 하나의 식으로 표현할 수 있게 해주는 기능입니다.
이름이 없는 함수를 람다로 정의하면 코드가 간결해지고 메서드의 불필요한 선언을 줄일 수 있어 가독성과 유지보수성이 높아집니다.
기본 형식 : (매개변수) -> { 표현식 또는 코드 블록 }
ex) (int x, int y) -> x + y
// 람다 표현식 이전
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};
// 람다 표현식 사용
Runnable r = () -> System.out.println("Hello, World!");
스트림은 데이터 컬렉션을 처리하기 위한 API로, 데이터의 반복 처리를 단순화하고 다양한 연산을 제공합니다.
스트림 API는 컬렉션 데이터를 함수형 프로그래밍 스타일로 처리할 수 있게 해줍니다.
기존 반복문(for, while)을 통해 데이터를 처리할 때마다 데이터의 흐름과 처리 방식을 명확하게 코딩해야 했지만, 스트림을 사용하면 각 단계를 선언적으로 표현할 수 있어 가독성과 유지보수성이 향상됩니다.
List<String> names = Arrays.asList("John", "Jane", "Doe", "Alice");
List<String> result = names.stream()
.filter(name -> name.startsWith("J"))
.collect(Collectors.toList());
System.out.println(result); // [John, Jane]
람다와 스트림은 자바의 코드 간결성과 병렬 처리 성능을 높이기 위해 생겨났다.
함수형 프로그래밍의 장점이 부각되면서, 자바도 보다 효율적이고 간결한 코드를 지원하기 위해 람다와 스트림을 도입하게 되었습니다.
람다 표현식은 함수형 프로그래밍을 지원하고, 스트림은 데이터 처리 로직을 단순화하면서도 병렬 처리(.parallelStream() 활용)를 가능하게 해줍니다. 이를 통해 코드의 가독성을 높이고 성능을 개선할 수 있었습니다.
어노테이션 : 클래스나 메서드에 메타 정보를 제공하기 위해 사용되는 도구.
어노테이션은 인터페이스를 기반으로 한 문법으로 주석처럼 코드에 달아 클래스에 특별한 의미를 부여하거나 기능을 주입할 수 있습니다. 자바 코드에 추가적인 메타데이터를 부여하여, 컴파일러에게 정보를 제공하거나 런타임 시 특정 동작을 지정할 수 있습니다.
컴파일러와 개발자에게 추가 정보를 전달하는 데 유용합니다.
@Override
public void run() {
System.out.println("This method overrides the superclass method.");
}
어노테이션마다의 역할이 각기 다르다.
컴파일러에게 힌트를 제공하는 어노테이션
런타임에 동작을 지정하는 어노테이션
메타 어노테이션 (어노테이션을 정의하기 위한 어노테이션)
코드의 가독성을 높이고 자동화된 동작을 위해 사용됩니다.
어노테이션을 사용하면 코드에 메타데이터를 부여하여 컴파일러가 특정 동작을 수행하거나, 개발자가 필요한 추가 정보를 확인할 수 있습니다.
또한, 자동화된 코드 생성, 런타임에서의 설정, 의존성 주입 등을 쉽게 할 수 있어 반복적인 작업을 줄이는 데 도움이 됩니다.
리플렉션 : 런타임에 클래스, 메서드, 필드 등의 정보를 조회하거나, 객체를 조작할 수 있는 강력한 기능입니다
리플렉션은 특히 런타임에 특정 어노테이션이 적용된 클래스나 메서드를 찾아내고, 그 어노테이션이 가진 정보를 읽어 동작을 결정하는 경우에 유용합니다.
예를 들어, @Service나 @Controller 같은 어노테이션이 붙은 클래스들을 스프링 프레임워크가 리플렉션으로 탐색하고, 이를 통해 자동으로 빈(bean)을 등록하는 방식이 대표적입니다.
스프링에서는 객체를 직접 생성하고 관리하는 대신, 컨테이너에 맡기는 방식을 채택합니다. 이 때, 스프링이 관리하는 객체를 빈이라고 부릅니다.
- 예를 들어, @Service가 붙은 클래스는 자동으로 서비스 역할을 하는 빈으로 등록되고, @Repository가 붙은 클래스는 DAO 역할을 하는 빈으로 등록됩니다.
- ItemService라는 빈이 있고, 다른 클래스에서 이를 @Autowired로 선언하면, 스프링이 해당 클래스의 인스턴스를 찾아서 자동으로 주입해 줍니다.
주로 스프링에서 구현해보았다.
스프링에서 @Controller, @Service, @Repository 같은 어노테이션이 붙은 클래스를 스캔하는 과정에서 리플렉션을 사용하여 해당 클래스들을 자동으로 빈으로 등록합니다. 의존성 주입을 위해 @Autowired가 붙은 필드나 생성자를 찾아 필요한 빈을 주입하는 것도 리플렉션을 통해 이루어집니다.
예시:
@Autowired
private ItemService itemService;
리플렉션을 통해 어노테이션이 붙은 메서드를 런타임에 찾아 실행할 수 있습니다. 프레임워크나 자동화 도구에서 이와 같은 메타데이터 처리를 많이 활용합니다.