java7 이하에서는 Callable 메소드를 생성하면 다음과 같은 형식으로 개발했다. 



import java.util.concurrent.Callable;

import java.util.concurrent.FutureTask;

...


                 String text = "1";

Callable<Integer> task = new Callable<Integer>() {

@Override

public Integer call() throws Exception {

return Integer.parseInt(text);

}

};


FutureTask<Integer> futureTask = new FutureTask<Integer>(task);

futureTask.run();

try {

System.out.println(futureTask.get());

} catch (Exception e) {

e.printStackTrace();

}




java8에서는 Callable의 call을 람다표현으로 깔끔하게 구성할 수 있다. 



import java.util.concurrent.Callable;

import java.util.concurrent.FutureTask;

...

String text = "1";

FutureTask<Integer> futureTask = new FutureTask<Integer>(() -> {

return Integer.parseInt(text);

});

futureTask.run();

try {

System.out.println(futureTask.get());

} catch (Exception e) {

e.printStackTrace();

}





그 이유는 java에서 @FunctionalInterface를 사용하는 코드는 알아서 람다 표현식으로 사용할 수 있게 한다.


@FunctionalInterface

public interface Callable<V> {

    /**

     * Computes a result, or throws an exception if unable to do so.

     *

     * @return computed result

     * @throws Exception if unable to compute a result

     */

    V call() throws Exception;

}


 

Runnable도 동일하다. 


@FunctionalInterface

public interface Runnable {

    /**

     * When an object implementing interface <code>Runnable</code> is used

     * to create a thread, starting the thread causes the object's

     * <code>run</code> method to be called in that separately executing

     * thread.

     * <p>

     * The general contract of the method <code>run</code> is that it may

     * take any action whatsoever.

     *

     * @see     java.lang.Thread#run()

     */

    public abstract void run();

}



비슷하게 Runable을 테스트해본다.



Runnable runabble = new Runnable() {

  @Override

  public void run() {

  System.out.println("Run!!");

  }

};

Thread th = new Thread(runabble);

th.start();

   Thread.sleep(1000);



위의 코드와 아래 코드는 동일하다. 


                Thread th = new Thread(() -> {

System.out.println("Run!!");

});

th.start();

              Thread.sleep(1000);





java8의 functional interface는 java language spec(https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8)에서 정의되어 있고 오직 하나의 abstract method으로 구성된다.


Invalid '@FunctionalInterface' annotation; ... is not a functional interface가 뜬다면 잘못 functional interface를 정의했다는 것을 컴파일에러로 알려준다. 



FunctionalInterface를 사용자 정의 선언을 할 수 있다. 


@FunctionalInterface

interface BindCallable {

public List<String> bind();

}


class Bind {

  public List<String> process(BindCallable callable){

    return callable.bind();

  }

}



간단한 예시이다. 


Bind bind = new Bind();

List<String> result = bind.process(() -> {

final String a = "a";

final String b = "b";

List<String> list = Lists.newArrayList();

list.add(a); list.add(b);

return list;

});

System.out.println(result);




Posted by 김용환 '김용환'

댓글을 달아 주세요