“I propose that after Java 9 we adopt a strict, time-based model with a new feature release every six months, update releases every quarter, and a long-term support release every three years.”
가장 큰 차이는 표현 그대로 지원의 차이라고 한다. 위 글과 같이 Java9 버전부터 6개월 마다 배포를 하고, LTS의 경우 3년 마다 배포를 하겠다고 한다. 그러므로 이와같은 특징들을 가진다.
위와 같은 특징을 가지므로, 실제 서비스 운영 환경(Production)에서는 LTS 버전을 권장한다.
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = new RunSomething() {
@Override
public void doIt() {
System.out.println("Hello");
}
};
// 람다 표현식
RunSomething runSomething1 = () -> System.out.println("Hello");
(인자 리스트) -> {바디}
// 인자가 없을 떄
Supplier<Integer> get10 = () -> {
return 10;
};
// 인자를 받을 때
BinaryOperator<Integer> sum = (a, b) -> a + b;
/*
* 인자의 타입은 생략이 가능, 컴파일러가 추론(infer)하지만 명시할 수도 있다.
* 여러 줄인 경우에 {} 사용, 한 줄인 경우에 생략 가능하며, return도 생략이 가능하다.
* */
/*
* 중첩클래스(Nested Class)의 경우 지역 변수(Local Variable)를 참조하는 경우 변수캡처(Variable Capture)가 일어난다.
* Java8 이전에는 final 키워드가 있어야만 참조가 가능했다.
* Java8 부터는 final 키워드는 해당 변수가 사실상 final인 경우(Effective final)에는 생략이 가능하다.
* 람다(Lambda)의 경우도 지역 변수를 참조하는 경우 변수캡처가 발생한다.
* 차이점은 Scope이다.
* 중첩클래스의 경우 해당 클래스의 Scope이 새로 생성되기 때문에, 그 안에서 지역 변수와 같은 이름의 변수선언 시 쉐도윙(Shadowing)이 발생한다.
* 하지만, 람다의 Scope는 새로운 Scope이 생성되는 것이 아닌 람다를 감싸고 있는 Scope과 같기 때문에 컴파일 에러를 발생시킨다.
* */
private void run() {
int baseNumber = 10;
// 지역 중첩 클래스(Local Inner Class)
// run() 메소드의 baseNumber를 변수캡처하여 사용하는 경우
class LocalClass{
void printBaseNumber(){
System.out.println(baseNumber);
}
}
// 익명 중첩 클래스(Anonymous Inner Class
// run() 메소드의 baseNumber를 쉐도윙(Shadowing)하는 경우
Consumer<Integer> integerConsumer = new Consumer<Integer>() {
int baseNumber = 20;
@Override
public void accept(Integer integer) {
System.out.println(baseNumber);
}
};
// 람다에서 local variable 참조하는 경우
IntConsumer printInt = (i) -> System.out.println(i + baseNumber);
printInt.accept(10);
}
/* 1.스태틱 메소드 참조 */
UnaryOperator<String> hi = Greeting::hi;
System.out.println(hi.apply("haeny"));
/* 2.특정 객체의 인스턴스 메소드 참조 */
Greeting greeting = new Greeting();
UnaryOperator<String> hello = greeting::hello;
System.out.println(hello.apply("haeny"));
/* 3.생성자 참조 */
// 인자가 없는 생성자를 참조
Supplier<Greeting> greetingSupplier = Greeting::new;
// String 인자를 받는 생성자를 참조
Function<String, Greeting> greetingFunction = Greeting::new;
/* 4.임의 객체의 인스턴스 메소드 참조 */
String[] names = {"haeny", "juhyun", "devillian"};
// Java8 이전
Arrays.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
});
// Java8에서 Comparator가 FunctionalInterface가 되었음.
Arrays.sort(names, (o1, o2) -> 0);
// 람다 자리에 메소드 레퍼런스를 사용
Arrays.sort(names, String::compareToIgnoreCase);
➕ Oracle Java SE Support Roadmap
➕ Lambda Expressions
➕ Nested Classes
➕ Method References