자바 8 튜토리얼
"Java는 아직 살아 있고 사람들은 이를 이해하기 시작했습니다."
Java 8 소개에 오신 것을 환영합니다. 이 기사에서는 Java 7에서 Java 8 까지의 모든 새로운 기능을 단계별로 안내합니다. 빠르고 간단한 코드 예제를 통해 기본 인터페이스,
메소드 참조
및 반복 가능한 주석 . 이 기사의 마지막 부분에서는 Stream API에 대해 알게 될 것입니다.
불필요한 잡담은 하지 마세요. 코드와 댓글만 있으면 됩니다! 앞으로!
인터페이스의 기본 방법
Java 8에서는
default
.
이 기능은 확장 방법 이라고도 합니다 . 다음은 첫 번째 예입니다.
interface Formula {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
추상 메소드 외에도
calculate
인터페이스는
Formula
기본 메소드도 정의합니다
sqrt
. 이 인터페이스를 구현하는 클래스는
calculate
. 기본 방법을
sqrt
즉시 사용할 수 있습니다.
Formula formula = new Formula() {
@Override
public double calculate(int a) {
return sqrt(a * 100);
}
};
formula.calculate(100);
formula.sqrt(16);
인터페이스는
Formula
익명 클래스로 구현됩니다. 코드가 중복됩니다. 구현을 위해 6줄이 필요합니다
sqrt(a * 100)
. 다음 섹션에서 살펴보겠지만 Java 8에는 단일 메서드를 구현하는 더 멋진 방법이 있습니다.
람다 표현식
이전 버전의 Java에서 문자열 목록을 정렬하는 간단한 예부터 시작해 보겠습니다.
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
정적 메서드는
Collections.sort
목록이 정렬되는 순서대로 목록과 비교기를 허용합니다. 언제든지 익명 비교기 클래스를 생성하여 전달할 수 있습니다. 익명 클래스를 만드는 대신 Java 8에서는 더 짧은 표기법인 람다 식을 만들 수 있습니다.
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
보시다시피 코드가 훨씬 짧고 읽기 쉽습니다. 하지만 다음과 같이 더 짧게 만들 수도 있습니다.
Collections.sort(names, (String a, String b) -> b.compareTo(a));
한 줄로 구성된 본문의 경우
{}
단어를 건너뛸 수 있습니다
return
. 하지만 더 짧게 만들 수도 있습니다.
Collections.sort(names, (a, b) -> b.compareTo(a));
Java 컴파일러는 인수 유형을 알고 있으므로 건너뛸 수도 있습니다. 람다 표현식을 더 자세히 살펴보고 사용 방법을 이해해 보겠습니다.
기능적 인터페이스
람다 표현식은 Java 유형 시스템에 어떻게 적합합니까? 각 람다는 인터페이스에 설명된 유형에 해당합니다. 따라서 기능적 인터페이스에는 하나의 추상 메서드만 포함되어야 합니다. 이 형식의 각 람다 식은 이 추상 메서드에 해당합니다. 기본 메서드는 추상적이지 않으므로 필요에 따라 기능적 인터페이스에서 기본 메서드를 자유롭게 만들 수 있습니다. 이 인터페이스에 추상 메서드가 하나만 있는 경우 임의의 인터페이스를 람다 식으로 사용할 수도 있습니다.
@FucntionalInterface
이러한 요구 사항을 충족하려면 주석을 추가해야 합니다 . 컴파일러는 이에 대해 알고 있으며 둘 이상의 추상 메소드를 제공하려는 경우 예외를 발생시킵니다. 예:
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted);
@FunctionalInterface
주석이 생략된 경우에도 코드가 컴파일된다는 점에 유의하세요 .
메서드 및 생성자 참조
위의 예제는 메서드 참조를 사용하여 더 작게 만들 수도 있습니다.
Converter<String, Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
System.out.println(converted);
Java 8에서는
::
. 위의 예에서는 정적 메서드를 참조하는 방법을 보여 주며, 비정적 메서드도 참조할 수 있습니다.
class Something {
String startsWith(String s) {
return String.valueOf(s.charAt(0));
}
}
Something something = new Something();
Converter<String, String> converter = something::startsWith;
String converted = converter.convert("Java");
System.out.println(converted);
생성자와 어떻게 작동하는지 살펴보겠습니다
::
. 시작하려면 다양한 생성자를 사용하여 예제 클래스를 정의합니다.
class Person {
String firstName;
String lastName;
Person() {}
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
다음으로, 새 객체를 생성하기 위한 인터페이스를 정의하겠습니다.
interface PersonFactory<P extends Person> {
P create(String firstName, String lastName);
}
생성 팩토리를 구현하는 대신
::
생성자 도움말을 사용하여 모든 것을 하나로 묶습니다.
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
를 통해 생성자에 대한 링크를 만들었습니다
Person::new
. Java 컴파일러는 메소드 서명과 일치하는 올바른 생성자를 자동으로 선택합니다
PersonFactory.create
. ... 계속됩니다. 아쉽게도 글의 초안을 저장할 방법을 찾지 못했는데, 이게 정말 이상하고, 번역 시간이 지났으니 나중에 마무리하도록 하겠습니다. 영어를 알고 이해하는 모든 사람을 위한
원본 기사입니다 . 번역 수정에 대한 제안 사항이 있는 경우 가능한 모든 방법으로 작성해 주십시오.
내 Github 계정
GO TO FULL VERSION