java 8 람다식 소개와 의미 고찰
Upcoming SlideShare
Loading in...5
×
 

java 8 람다식 소개와 의미 고찰

on

  • 7,072 views

Java 8의 람다식(Lambda Expression)의 사용 방법과 람다가 도입된 이유, 람다와 함께 추가된 API, 언어적인 변화를 간단히 정리

Java 8의 람다식(Lambda Expression)의 사용 방법과 람다가 도입된 이유, 람다와 함께 추가된 API, 언어적인 변화를 간단히 정리

Statistics

Views

Total Views
7,072
Views on SlideShare
6,892
Embed Views
180

Actions

Likes
94
Downloads
153
Comments
11

9 Embeds 180

http://blog.studioego.info 93
http://www.slideee.com 45
https://twitter.com 29
http://aegyo.net 5
http://blog.naver.com 2
http://feedly.com 2
http://studioego.tistory.com 2
http://www.hanrss.com 1
https://www.docsnode.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial LicenseCC Attribution-NonCommercial License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

15 of 11 Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • 좋은 자료 잘 봤습니다. 감사합니다.
    Are you sure you want to
    Your message goes here
    Processing…
  • 30분 안에 발표하려고 좀 내용을 함축했는데 잘 봐주셔서 고맙습니다.
    Are you sure you want to
    Your message goes here
    Processing…
  • 좋은 자료 잘 봤습니다. 근래 본 람다식 설명중 가장 명확하게 설명이 되어 있는거 같아요^^
    Are you sure you want to
    Your message goes here
    Processing…
  • 감사합니다. ^_____________________^
    Are you sure you want to
    Your message goes here
    Processing…
  • 동영상은 처음 두 파트 밖에 설명 못했습니다. 애초에 시간 부족할 것은 알았고요. 그래서 세번째부터는 자료 보시면 아시겠지만 설명식이 아닌 사전식(?)으로 장표가 작성되어 있습니다. 나중에 참고라도 하라고...

    그리고 제가 Thread().run()이라고 예제에 써놨네요. Thread().start()로 고쳤습니다. (뭔 정신으로 쓴 건지...)
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

java 8 람다식 소개와 의미 고찰 java 8 람다식 소개와 의미 고찰 Presentation Transcript

  • 자바 8 람다의 이해와 의미 Java 8 Lambda 자바 8의 핵심 개선 사항인 람 다의 정확한 성격을 고찰하고 람다가 자바 개발에 미칠 영향 을 얘기합니다. 박성철
  • 속성 주입식 람다 설명
  • 인터페이스 (Interface)
  • 함수형 인터페이스 (Functional Interface)
  • 함수형 인터페이스 (Functional Interface) 추상 메서드가 하나 뿐인 모든 인터페이스
  • package
  •   java.lang;
  •    ! public
  •    interface
  •   Runnable
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   abstract
  •   void
  •   run();
  •    } 인터페이스 메서드 하나 함수형 인터페이스 인정! Runnable
  • public
  •   class
  •   AsyncHelloWorld
  •   {
  •    ! 
  •   
  •   
  •   
  •   public
  •   static
  •   class
  •   HelloWorld
  •   implements
  •   Runnable
  •   {
  •    ! 
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   @Override
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   void
  •   run()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("Hello
  •   World!");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •    
  •   
  •   
  •   
  •   }
  •    ! 
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   args)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   new
  •   Thread(new
  •   HelloWorld()).start();
  •    
  •   
  •   
  •   
  •   }
  •    } 자바 ~7 쓰레드 생성 클래스 정의 객체 생성
  • public class AsyncHelloWorld { public static void main(String[] args) { new Thread(() -> { System.out.println("Hello World!"); }).start(); } } 자바 8 쓰레드 생성 람다식
  • 자바 7 vs. 자바 8 public
  •   class
  •   AsyncHelloWorld
  •   {
  •    ! 
  •   
  •   
  •   
  •   public
  •   static
  •   class
  •   HelloWorld
  •   implements
  •   Runnable
  •   {
  •    ! 
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   @Override
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   void
  •   run()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("Hello
  •   World!");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •    
  •   
  •   
  •   
  •   }
  •    ! 
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   args)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   new
  •   Thread(new
  •   HelloWorld()).start();
  •    
  •   
  •   
  •   
  •   }
  •    } public
  •   class
  •   AsyncHelloWorld
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   args)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   new
  •   Thread(()
  •   ->
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("Hello
  •   World!");
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }).start();
  •    
  •   
  •   
  •   
  •   }
  •    }
  • 람다식 문법 (인자 목록) -> { 구문 } 람다식 = 익명 메서드 public
  •   void
  •   sayHello(PrintStream
  •   out)
  •   {
  •    
  •   
  •   
  •   
  •   out.println("Hello
  •   World!");
  •    } (PrintStream
  •   out)
  •   ->
  •   {
  •   out.println("Hello
  •   World!");}
  • 대상 타입 추론 new
  •   Thread(()
  •   ->
  •   {
  •    
  •   
  •   
  •   
  •   System.out.println("Hello
  •   World!");
  •    }).start(); public
  •   Thread(Runnable
  •   target) new
  •   Thread(
  •   new
  •   Runnable()
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   void
  •   run()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   System.out.println("Hello
  •   World!");
  •    
  •   
  •   
  •   
  •   }
  •    }).start(); 대상 타입(Target Type) 함수형 인터페이스 public
  •   interface
  •   Runnable
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   abstract
  •   void
  •   run();
  •    } ≃
  • 매개변수 타입 추론 b.addActionListener((ActionEvent e) -> {! counter.inc();! text.setText(“버튼 클릭: " + counter.count() + " 회");! }); public
  •   void
  •   addActionListener(ActionListener
  •   l) b.addActionListener((e) -> {! counter.inc();! text.setText(“버튼 클릭: " + counter.count() + " 회");! }); public
  •   interface
  •   ActionListener
  •   {
  •    
  •   
  •   
  •   
  •   void
  •   actionPerformed(ActionEvent
  •   e);
  •    }
  •   
  • (n,
  •   str)
  •   ->
  •   str
  •   +
  •   n 람다식 예 (int
  •   n,
  •   String
  •   str)
  •   ->
  •   str
  •   +
  •   n str
  •   ->
  •   str
  •   +
  •   1 ()
  •   ->
  •   “Hello,
  •   World!” (int
  •   n,
  •   String
  •   str)
  •   ->
  •   {
  •   return
  •   str
  •   +
  •   n;} ()
  •   ->
  •   {}
  • 요약 • 함수형 인터페이스 • 람다식 (인자 목록) -> { 구문 블럭 } 또는 (인자 목록) -> 식 • 람다식 = 익명 메서드 • 대상 타입 • 매개변수 타입 추론 • 다양한 축약형 람다식
  • 람다식은 뭐에 써 먹는 놈이냐? https://www.flickr.com/photos/rofi/2097239111/
  • 제어 흐름 중복 assert numbers.length > 0;! ! int max = numbers[0];! for(int i=1;! i < numbers.length;! i++)! if(Math.abs(max) < ! Math.abs(numbers[i])! max = numbers[i];! return max;! assert numbers.length > 0;! ! int max = numbers[0];! for(int i=1; ! i < numbers.length; ! i++)! if(max < numbers[i])! max = numbers[i];! return max;
  • 템플릿 메소드 패턴 AbstractMaxFinder public findMax(list) abstract boolean isLesser(a, b) NaturalMaxFinder boolean isLesser(a, b) AbsNumberMaxFinder boolean isLesser(a, b) 안 변하는 것 변하는 것
  • 전략 패턴 <interface> Camparator abstract boolean isLesser(a, b) NaturalNumberComparator boolean isLesser(a, b) AbsNumberCamparator boolean isLesser(a, b) MaxFinder public findMax(list) 안 변하는 것 변하는 것
  • • 제어 흐름 재사용 • 코드 중복 제거 • 유연성 향상 • 코드 변경 주기 기준 분리 제어 흐름 추상화 OOP의 제어 흐름 추상화 기법 • 상속을 통한 제어 흐름 추상화: 템플릿 메서드 패턴 • 위임을 통한 제어 흐름 추상화: 전략 패턴
  • https://www.flickr.com/photos/m2w2/191545978/
  • https://www.flickr.com/photos/chazferret/2842411103/
  • •메서드 호출시 값을 인자로 전달하듯 행위를 전달 •런타임에 행위를 전달받아서 미리 정해진 제어 흐름에 따라 수행 •객체가 아닌 메서드(또는 함수) 수준의 제어 흐름 추상화 •객체를 사용하는 방법보다 경량 •함수형의 고차함수(Higher Order Function) 행위 매개변수
 (Paramterized Behaviors) function
  •   forEach(array,
  •   func)
  •   {
  •    
  •   
  •   for
  •   (var
  •   i
  •   =
  •   0;
  •   i
  •   <
  •   array.length;
  •   i++)
  •    
  •   
  •   
  •   
  •   func(array[i]);
  •    }
  •    ! sum
  •   =
  •   0
  •    forEach([1,
  •   2,
  •   3,
  •   4,
  •   5],,
  •   function(number)
  •   {
  •   sum
  •   +=
  •   number
  •   }) 자바스크립트의 고차함수
  • 자바의 행위 매개변수 java.util.Collections
  •    ! public
  •   static
  •   <T>
  •   T
  •   max(Collection<?
  •   extends
  •   T>
  •   coll,
  •   Comparator<?
  •   super
  •   T>
  •   comp)
  •    public
  •   static
  •   <T>
  •   T
  •   min(Collection<?
  •   extends
  •   T>
  •   coll,
  •   Comparator<?
  •   super
  •   T>
  •   comp)
  •    public
  •   static
  •   <T>
  •   void
  •   sort(List<T>
  •   list,
  •   Comparator<?
  •   super
  •   T>
  •   c) •모든 코드는 Class 안에 정의되어야 함(함수만 인자로 사용 불가). •모든 자바 소스 파일에 공개 클래스(public class)나 인터페이스 하나 - 자바 코드 관례 •클래스 이름 작명 필요 •각종 상용구(boilerplate code) •캡슐화, 간접 접근 자바 객체 사용 비용
  • 익명 클래스 List<User>
  •   users
  •   =
  •   new
  •   ArrayList<User>();
  •    Collections.sort(users,
  •   new
  •   Comparator<User>()
  •   {
  •    
  •   
  •   
  •   
  •   @Override
  •    
  •   
  •   
  •   
  •   public
  •   int
  •   compare(User
  •   user1,
  •   User
  •   user2)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   user1.getAge()
  •   -
  •   user2.getAge();
  •    
  •   
  •   
  •   }
  •    }); 익명 클래스를 사용한 행위 인자 • 가장 비용이 적게 드는 클래스 • 클래스 정의와 인스턴스 생성이 동시 • 클래스 이름 작명 불필요런 • 클래스 생성자 작성 불필요 • 1 회용 클래스: 클래스 하나에 인스턴스 하나
  • 변수 포획 (Captured Variable) Button b = new Button("누르시오”); final TextField text = new TextField(20); final Counter counter = new Counter(); ! b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter.inc(); text.setText(“버튼 클릭: " + counter.count() + " 회"); } }); • 내부 객체는 외부객체의 멤버와 외곽 범주(scope)의 변수 값에 접근 가능 • 내부 객체가 접근할 변수는 final 수정 기호로 고정되어야 함 익명 클래스( + 변수 포획) = 자바식 클로저(Closure)
  • https://www.flickr.com/photos/chazferret/2842411103/ 템플릿-콜백 패턴
  • 행위 매개변수의 보급 • 다양한 언어에서 고차함수 지원 • 함수형 프로그래밍 대중화 • 스프링 xxxTemplate • C# 3.0 람다식 지원 & .Net 프레임워크(LINQ) (2007) • 자바의 수다스러운 구문에 대한 반발: Guava, LambdaJ, Op4j List<Actor>
  •   actors
  •   =
  •   this.jdbcTemplate.query(
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   "select
  •   first_name,
  •   last_name
  •   from
  •   t_actor",
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   new
  •   RowMapper<Actor>()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   Actor
  •   mapRow(ResultSet
  •   rs,
  •   int
  •   rowNum)
  •   throws
  •   SQLException
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Actor
  •   actor
  •   =
  •   new
  •   Actor();
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   actor.setFirstName(rs.getString("first_name"));
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   actor.setLastName(rs.getString("last_name"));
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   actor;
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   }); 스프링 프레임워크의 JdbcTemplate 사용 예 람다식 지원 필요 급증
  • 결국… List<User>
  •   users
  •   =
  •   …⋯
  •    Collections.sort(users,
  •   new
  •   Comparator<User>()
  •   {
  •    
  •   
  •   
  •   
  •   @Override
  •    
  •   
  •   
  •   
  •   public
  •   int
  •   compare(User
  •   u1,
  •   User
  •   u2)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   u1.getAge()
  •   -
  •   u2.getAge();
  •    
  •   
  •   
  •   }
  •    }); List<User>
  •   users
  •   =
  •   …⋯
  •    Collections.sort(users,
  •   (u1,
  •   u2)
  •   ->
  •   u1.getAge()
  •   -
  •   u2.getAge());
  • 요약 • 제어 흐름의 중복과 추상화 • OOP 방식: OOP is not a one-size-fits-all solution. • 행위 매개변수를 사용한 제어 흐름 추상화 • 가장 비용이 적게 드는 익명 클래스 • 변수 포획 • 행위 매개변수의 대중화 • 자바, 람다식 지원
  • 스트림(Streams) API https://www.flickr.com/photos/23209605@N00/2786126623/
  • 반복의 내재화 for(int
  •   n:
  •   numbers)
  •   {
  •    
  •   
  •   
  •   
  •   …⋯
  •    } numbers.forEach(n
  •   ->
  •   …⋯) Collection Stream 외부 반복
 External Iteration 내부 반복
 Internal Iteration • 명시적 외부 반복 • 제어 흐름 중복 발생 • 효율적이고 직접적인 요소 처리 • 지저분한 코드 • 유한 데이터 구조 API • 반복 구조 캡슐화 • 제어 흐름 추상화 • 파이프-필터 기반 API • 최적화와 알고리듬 분리 • 함축적인 표현 • 무한 연속 데이터 흐름 API • 데이터 외 I/O, 값 생성 등 적용
  • 스트림 유형 DoubleStream java.util.stream IntStream LongStream Stream<T> 객체를
  •   요소로
  •   하는
  •   가장
  •   일반적인
  •   스트림 요소가
  •   double인
  •   스트림 요소가
  •   int인
  •   스트림 요소가
  •   long인
  •   스트림 java.lang Optional<T> 값이
  •   있을
  •   수도
  •   없을
  •   수도
  •   있을
  •   때
  •   사용
  • 스트림 생성 stream(),
  •   parallelStream()Collection BufferedReader lines() Random doubles(*),
  •   ints(*),
  •   longs(*) BitSet IntStream() Arrays stream(*) of(*),
  •   range(…⋯)Stream 유형 xxxStream.Builder build()
  • 스트림 중개 연산자 Stream<R>
  •   map(Function<?
  •   super
  •   T,?
  •   extends
  •   R>
  •   mapper)
  •    T 타입의 요소를 1:1로 R 타입의 요소로 변환 후 스트림 생성 Stream<T>
  •   filter(Predicate<?
  •   super
  •   T>
  •   predicate)
  •    T 타입의 요소를 확인해서 기준에 통과한 요소만으로 새 스트림 생성 Stream<R>
  •   flatMap(Function<T,Stream<?
  •   extends
  •   R>>
  •   mapper)
  •    T 타입의 요소를 1:n으로 R 타입의 요소로 변환 후 스트림 생성, Monad bind() Stream<T>
  •   skip(long
  •   n) 처음 n개의 요소를 제외한 나머지 요소로 새 스트림 생성 Stream<T>
  •   limit(long
  •   n)
  •   처음 n개의 요소로 새 스트림 생성 IntStream.range(1,
  •   100).filter(n
  •   ->
  •   n
  •   %
  •   2
  •   ==
  •   0).map(n
  •   ->
  •   n*n).skip(10).limit(10) 무상태 연산
  • 중개 연산자 관련 함수형 인터페이스 java.util.function.* !•!Predicate<T> T 타입의 인자를 검증해서 boolean 값 반환
 boolean test(T t) !•!Consumer<T> T 타입의 인자를 처리
 void accept(T t) !•!Function<T,R> T 타입의 인자를 받아 R 타입의 값으로 변환
 R apply(T t) !•!Supplier<T> T 타입의 값을 생성해서 반환
 T get() !•!UnaryOperator<T> T 타입의 값을 받아 T 타입의 값을 반환
 T apply(T t) !•!BinaryOperator<T> T 타입의 두 값을 받아 T타입의 값을 반환
 T apply(T t, T u)
  • 스트림 중개 연산자 Stream<T>
  •   sorted() 정렬된 스트림 생성, T 타입은 Comparable을 구현한 타입 Stream<T>
  •   sorted(Comparator<?
  •   super
  •   T>
  •   comparator)
  •   정렬된 스트림 생성 Stream<T>
  •   distinct()
  •   중복된 요소를 제거한 스트림 생성 내부 상태 유지 연산
  • 스트림 종단 연산자 void
  •   forEach(Consumer<?
  •   super
  •   T>
  •   consumer)
  •    T 타입의 요소를 하나씩 처리 R
  •   collect(Collector<?
  •   super
  •   T,R>
  •   collector)
  •    T 타입의 요소를 모두 모아 하나의 자료구조나 값으로 변환 Optional<T>
  •   reduce(BinaryOperator<T>
  •   reducer)*
  •    T 타입의 요소 둘 씩 reducer로 계산해 최종적으로 하나의 값을 계산 Iterator<T>
  •   iterator() Iterator 객체 반환 IntStream.range(1,
  •   100).filter(n
  •   ->
  •   n
  •   %
  •   2
  •   ==
  •   0).map(n
  •   ->
  •   n*n)
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .skip(10)
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .limit(10)
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .reduce(0,
  •   Integer::sum)
  • 지연 연산과 병렬 처리 • 스트림을 반환하는 필터와 맵 연산은 기본적으로 지연(lazy) 연산 • 지연 연산을 통한 성능 최적화 (무상태 중개 연산) • 종단 연산 시 모든 연산 수행 (반복 작업 최소화) 지연 연산 • 동일한 코드로 순차 연산과 병렬 연산 모두 지원, 선택 가능 • 순차 연산에서 parallel() 메서도로 병렬 연산으로 전환 가능 • Collection.parallelStream()으로 병렬 처리 스트림 생성 가능 • 경고: 스트림 처리 중에는 스트림 요소를 변경하지 마시오! • 쓰레드 안전하지 않은 컬렉션에서도 병렬처리 수행 병렬 처리 Stream
  •   usersStream
  •   =
  •   users.parallelStream();
  •    int
  •   sum
  •   =
  •   usersStream.filter(u
  •   ->
  •   u.getSex()
  •   ==
  •   MALE)
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .mapToInt(u
  •   ->
  •   u.getWeight())
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   .sum();
  • 요약 • 스트림: 컬랙션(Collection) 프레임워크보다 한 단계 더 높은 추상화 제공 • 내부 반복 • 중개 연산: 파이프와 필터, 맵(Map) • 종단 연산: 결과 생산(Reduce) • 지연 연산을 통한 최적화 • 병렬 처리 추상화 • 컬랙션 외 다양한 연속적 데이터에 적용
  • 함수의 재발견? https://www.flickr.com/photos/vestman/4908148942/
  • 인터페이스 하위 호환성 문제 • 경직된 자바 인터페이스, 메서드 추가 후 하위 호환성 상실 • 인터페이스에 메서드 추가 후 모든 클래스를 다시 컴파일 해야 함 • 공개된 API는 불가능 • 다양한 우회 기법 활용 • 애플리케이션: 하위 호환성 포기(1) • 자바 SDK: 무수정, 도움 객체 사용(Collections) • Eclipse: 확장 인터페이스 추가(ISomeRole -> ISomeRoleExtension) • 중도: 기본 추상 클래스를 통한 확장(ISomeRole -> AbstractSomeRole) • 람다식과 함께 대규모로 자바 SDK를 수정하려고 하면서 문제 발생 (1)
  •   http://blog.jooq.org/2013/02/01/defensive-api-evolution-with-java-interfaces/
  • 기본 메서드(Default Method) • 인터페이스에 기본 구현 포함 가능, 추가된 인터페이스의 하위 호환성 보장 • default 키워드 사용 • 함수형 인터페이스 조건에서 제외 • 인터페이스 확장시 재구현 또는 추상(abstract)으로 재지정 가능 • 가상 확장 메서드(virtual extension methods) 또는 방어 메서드(defender methods)라는 이름도 사용 public
  •   interface
  •   Iterator<E>
  •   {
  •    ! 
  •   
  •   
  •   
  •   …⋯…⋯
  •    ! 
  •   
  •   
  •   
  •   default
  •   void
  •   remove()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   throw
  •   new
  •   UnsupportedOperationException("remove");
  •    
  •   
  •   
  •   
  •   }
  •    ! 
  •   
  •   
  •   
  •   default
  •   void
  •   forEachRemaining(Consumer<?
  •   super
  •   E>
  •   action)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Objects.requireNonNull(action);
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   while
  •   (hasNext())
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   action.accept(next());
  •    
  •   
  •   
  •   
  •   }
  • 기본 메서드와 상속 • 클래스의 구현이 인터페이스의 기본 구현보다 우선 • 가장 구체적인 구현(most specific implementation)에 우선권 부여 • 다이아몬드 문제 발생 가능 • 컴파일 오류 발생(T inherits unrelated defaults for x()) • 명시적인 오버라이드 필요 • 충돌하는 둘 이상의 수퍼타입 중 선호하는 수퍼타입을 선택할 수 있음 • 타입 다중 상속, 행위 다중 상속은 지원하지만 상태 다중 상속은 미지원 interface
  •   Robot
  •   implements
  •   Artist,
  •   Gun
  •   {
  •    
  •   
  •   
  •   
  •   default
  •   void
  •   draw()
  •   {
  •   Artist.super.draw();
  •   }
  •    }
  • 인터페이스 정적 메서드 • 인터페이스에 정적 메서드 포함 가능 • 인터페이스에 필요한 정적 메서드를 별도 유틸리티 클래스로 분리할 필요 없음 public
  •   interface
  •   Function<T,
  •   R>
  •   {
  •    ! 
  •   
  •   
  •   
  •   R
  •   apply(T
  •   t);
  •    
  •   
  •    
  •   
  •   
  •   
  •   static
  •   Function<?,
  •   String>
  •   toStringFunction()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   value
  •   ->
  •   value.toString();
  •    
  •   
  •   
  •   
  •   }
  •    
  •   
  •    
  •   
  •   
  •   
  •   static
  •   <E>
  •   Function<E,
  •   E>
  •   identity()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   value
  •   ->
  •   value;
  •    
  •   
  •   
  •   
  •   }
  •    
  •   
  •    
  •   
  •   
  •   
  •   static
  •   <R>
  •   Function<?,
  •   R>
  •   constant(R
  •   constantValue)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   return
  •   value
  •   ->
  •   constantValue;
  •    
  •   
  •   
  •   
  •   }
  •    }
  • 자바 5의 정적 임포트 • 자바 5에서 클래스 맴버(또는 정적 맴버) 임포트 기능 추가
 import
  •   static
  •   java.lang.Math.*;
  •    • 상속 없이 특정 클래스나 인터페이스의 정적 멤버에 직접 접근
 상수 인터페이스 안티패턴 예방
 double
  •   r
  •   =
  •   cos(PI
  •   *
  •   theta);
  •    • 클래스 메서드를 전역 함수로 사용하는 효과 • 클래스 메서드(정적 메서드) 사용 빈도 확대, 서술적인 API
 import
  •   static
  •   org.junit.Assert.*;
 import
  •   static
  •   org.mockito.Mockito.*;
  •    • 람다와 인터페이스 정적 메서드와 시너지 기대 import
  •   static
  •   com.mysema.query.alias.Alias.*;
  •    ! Cat
  •   c
  •   =
  •   alias(Cat.class,
  •   "cat");
  •    for
  •   (String
  •   name
  •   :
  •   
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   from($(c),cats).where($(c.getKittens()).size().gt(0)).list($(c.getName()))){
  •    
  •   
  •   
  •   
  •   System.out.println(name);
  •    }
  • 요약 • 인터페이스에 메서드 구현 허용: 기본 메서드, 정적 메서드 • 기본 메서드: 인터페이스 메서드 추가로 인한 하위 호환성 문제 해결 • 정적 메서드: 별도 헬퍼 클래스 불필요 • 자바 5의 정적 메서드 임포트, 정적 메서드, 람다식의 혼용으로 전역 함수 활용 활성화 예상
  • 기타 등등… https://www.flickr.com/photos/ilmungo/115943573/
  • 익명 클래스 생성 public
  •   class
  •   SimpleApp
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   args)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Runnable
  •   runnable
  •   =
  •   new
  •   Runnable()
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   @Override
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   public
  •   void
  •   run()
  •   {
  •   
  •   }
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   };
  •    
  •   
  •   
  •   
  •   }
  •    } 
  •   
  •   public
  •   static
  •   void
  •   main(java.lang.String[]);
  •    
  •   
  •   
  •   
  •   Code:
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   0:
  •   new
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   #2
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   class
  •   org/fupfin/java8/lambda/SimpleApp$1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   3:
  •   dup
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   4:
  •   invokespecial
  •   #3
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   Method
  •   org/fupfin/java8/lambda/SimpleApp $1."<init>":()V
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   7:
  •   astore_1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   8:
  •   return
  • 
  •   
  •   public
  •   static
  •   void
  •   main(java.lang.String[]);
  •    
  •   
  •   
  •   
  •   Code:
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   0:
  •   invokedynamic
  •   #2,
  •   
  •   0
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   InvokeDynamic
  •   #0:run:()Ljava/lang/ Runnable;
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   5:
  •   astore_1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   6:
  •   return 람다 public
  •   class
  •   SimpleApp
  •   {
  •    
  •   
  •   
  •   
  •   public
  •   static
  •   void
  •   main(String[]
  •   args)
  •   {
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   Runnable
  •   runnable
  •   =
  •   ()
  •   ->
  •   {};
  •    
  •   
  •   
  •   
  •   }
  •    }
  • 람다 != 익명 클래스 
  •   
  •   public
  •   static
  •   void
  •   main(java.lang.String[]);
  •    
  •   
  •   
  •   
  •   Code:
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   0:
  •   new
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   #2
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   class
  •   org/fupfin/java8/lambda/SimpleApp$1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   3:
  •   dup
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   4:
  •   invokespecial
  •   #3
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   Method
  •   org/fupfin/java8/lambda/SimpleApp $1."<init>":()V
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   7:
  •   astore_1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   8:
  •   return 
  •   
  •   public
  •   static
  •   void
  •   main(java.lang.String[]);
  •    
  •   
  •   
  •   
  •   Code:
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   0:
  •   invokedynamic
  •   #2,
  •   
  •   0
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   
  •   //
  •   InvokeDynamic
  •   #0:run:()Ljava/lang/ Runnable;
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   5:
  •   astore_1
  •    
  •   
  •   
  •   
  •   
  •   
  •   
  •   6:
  •   return JSR 292
  • 객체메서드 참조 public class AsyncHelloWorld { ! private static void sayHelloWorld() { System.out.println("Hello World!"); } ! public static void main(String[] args) { new Thread(() -> sayHelloWorld()).start(); } } AsyncHelloWorld::sayHelloWorld IntStream.range(1, 32).mapToObj(Integer::toHexString) IntStream.range(1, 10).forEach(System.out::println); IntStream.range(-10, 10).map(Math::abs)정적 메서드 특정 객체의 메서드 임의의 객체의 메서드
  • 사실상 final Button b = new Button("누르시오”); TextField text = new TextField(20); Counter counter = new Counter(); ! b.addActionListener( e -> { counter.inc(); text.setText(“버튼 클릭: " + counter.count() + " 회"); } ); final 수정기호를 명기하지 않아도 수정되지 않는다면 변수 포획