자바 8 람다 무효 인수
Java 8에서 다음과 같은 기능 인터페이스가 있다고 가정 해 봅시다.
interface Action<T, U> {
U execute(T t);
}
그리고 어떤 경우에는 인수 또는 반환 유형이없는 작업이 필요합니다. 그래서 다음과 같이 씁니다.
Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };
그러나 컴파일 오류가 발생하므로 다음과 같이 작성해야합니다.
Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};
못생긴 것입니다. Void
type 매개 변수를 제거하는 방법이 있습니까?
다음 구문은 a Runnable
로 변환하는 작은 도우미 함수로 가능합니다 Action<Void, Void>
( Action
예 : 배치 할 수 있음 ).
public static Action<Void, Void> action(Runnable runnable) {
return (v) -> {
runnable.run();
return null;
};
}
// Somewhere else in your code
Action<Void, Void> action = action(() -> System.out.println("foo"));
Supplier
아무것도 걸리지 않지만 무언가를 반환하면 사용하십시오 .
Consumer
무언가가 필요하지만 아무것도 반환하지 않으면 사용하십시오 .
Callable
결과를 반환하고 던질 수있는 경우에 사용하십시오 ( Thunk
일반적인 CS 용어 와 유사 ).
Runnable
던지지 않고 던질 수없는 경우 사용하십시오 .
람다 :
() -> { System.out.println("Do nothing!"); };
실제로 다음과 같은 인터페이스에 대한 구현을 나타냅니다.
public interface Something {
void action();
}
정의한 것과는 완전히 다릅니다. 그래서 오류가 발생합니다.
를 확장하거나 @FunctionalInterface
새로운 것을 소개 할 수 없으므로 많은 옵션이 없다고 생각합니다. Optional<T>
인터페이스를 사용하여 일부 값 (반환 유형 또는 메소드 매개 변수)이 누락되었음을 표시 할 수 있습니다 . 그러나 이것은 람다 본문을 더 단순하게 만들지는 않습니다.
해당 특수한 경우에 대한 하위 인터페이스를 만들 수 있습니다.
interface Command extends Action<Void, Void> {
default Void execute(Void v) {
execute();
return null;
}
void execute();
}
기본 메서드 를 사용 하여 상속 된 매개 변수화 된 메서드 를 재정 Void execute(Void)
의하여 더 간단한 메서드에 대한 호출을 위임합니다 void execute()
.
결과적으로 사용이 훨씬 간단 해집니다.
Command c = () -> System.out.println("Do nothing!");
불가능합니다. 무효가 아닌 반환 유형을 가진 함수 Void
는 값을 반환해야합니다. 그러나 정적 메소드를 추가하여 Action
다음과 같이 "생성"할 수 있습니다 Action
.
interface Action<T, U> {
U execute(T t);
public static Action<Void, Void> create(Runnable r) {
return (t) -> {r.run(); return null;};
}
public static <T, U> Action<T, U> create(Action<T, U> action) {
return action;
}
}
그러면 다음을 쓸 수 있습니다.
// create action from Runnable
Action.create(()-> System.out.println("Hello World")).execute(null);
// create normal action
System.out.println(Action.create((Integer i) -> "number: " + i).execute(100));
기능적 인터페이스 내에 정적 메소드 추가
package example;
interface Action<T, U> {
U execute(T t);
static Action<Void,Void> invoke(Runnable runnable){
return (v) -> {
runnable.run();
return null;
};
}
}
public class Lambda {
public static void main(String[] args) {
Action<Void, Void> a = Action.invoke(() -> System.out.println("Do nothing!"));
Void t = null;
a.execute(t);
}
}
산출
Do nothing!
함수 정의가 예제에서 일치하지 않기 때문에 가능하지 않다고 생각합니다.
람다 식은 다음과 같이 정확하게 평가됩니다
void action() { }
당신의 선언은 다음과 같습니다
Void action(Void v) {
//must return Void type.
}
예를 들어 다음과 같은 인터페이스가있는 경우
public interface VoidInterface {
public Void action(Void v);
}
호환되는 유일한 기능 (인스턴스화 중)은 다음과 같습니다.
new VoidInterface() {
public Void action(Void v) {
//do something
return v;
}
}
return 문이나 인수가 없으면 컴파일러 오류가 발생합니다.
Therefore, if you declare a function which takes an argument and returns one, I think it is impossible to convert it to function which does neither of mentioned above.
Just for reference which functional interface can be used for method reference in cases method throws and/or returns a value.
void notReturnsNotThrows() {};
void notReturnsThrows() throws Exception {}
String returnsNotThrows() { return ""; }
String returnsThrows() throws Exception { return ""; }
{
Runnable r1 = this::notReturnsNotThrows; //ok
Runnable r2 = this::notReturnsThrows; //error
Runnable r3 = this::returnsNotThrows; //ok
Runnable r4 = this::returnsThrows; //error
Callable c1 = this::notReturnsNotThrows; //error
Callable c2 = this::notReturnsThrows; //error
Callable c3 = this::returnsNotThrows; //ok
Callable c4 = this::returnsThrows; //ok
}
interface VoidCallableExtendsCallable extends Callable<Void> {
@Override
Void call() throws Exception;
}
interface VoidCallable {
void call() throws Exception;
}
{
VoidCallableExtendsCallable vcec1 = this::notReturnsNotThrows; //error
VoidCallableExtendsCallable vcec2 = this::notReturnsThrows; //error
VoidCallableExtendsCallable vcec3 = this::returnsNotThrows; //error
VoidCallableExtendsCallable vcec4 = this::returnsThrows; //error
VoidCallable vc1 = this::notReturnsNotThrows; //ok
VoidCallable vc2 = this::notReturnsThrows; //ok
VoidCallable vc3 = this::returnsNotThrows; //ok
VoidCallable vc4 = this::returnsThrows; //ok
}
참고URL : https://stackoverflow.com/questions/29945627/java-8-lambda-void-argument
'IT' 카테고리의 다른 글
div 요소 내부의 텍스트를 바꾸려면 어떻게합니까? (0) | 2020.06.03 |
---|---|
확인란의 값을 가져 옵니까? (0) | 2020.06.03 |
CSS 표시 속성을 기본값으로 재설정 (0) | 2020.06.02 |
.NET 4.0에서 Microsoft.csharp.dll은 (는) 무엇 이죠 (0) | 2020.06.02 |
Linux의 C ++ 동적 공유 라이브러리 (0) | 2020.06.02 |