Java 8 lamda Void 인수
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
유형 매개 변수?
아무 것도 안 가져갔지만, 뭔가를 돌려줄 때 사용하세요.
무언가를 가져갔지만 아무것도 반환하지 않을 때 사용합니다.
결과를 반환하고 던질 수 있는 경우 사용합니다(일반 CS 용어와 가장 유사합니다).
던지지 않고 던질 수 없는 경우에 사용합니다.
이 테이블은 짧고 쓸모 있는 것 같습니다.
Supplier () -> x
Consumer x -> ()
BiConsumer x, y -> ()
Callable () -> x throws ex
Runnable () -> ()
Function x -> y
BiFunction x,y -> z
Predicate x -> boolean
UnaryOperator x1 -> x2
BinaryOperator x1,x2 -> x3
다른 답변에서 설명한 바와 같이 이 문제에 대한 적절한 옵션은Runnable
원하는 구문은 작은 도우미 함수로 가능합니다.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"));
람다:
() -> { 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() { }
하지만 당신의 선언은
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 스테이트먼트 또는 인수가 없으면 컴파일러 오류가 발생합니다.
따라서 인수를 사용하여 반환하는 함수를 선언하면 위의 어느 함수도 아닌 함수로 변환하는 것은 불가능하다고 생각합니다.
그건 불가능해요.비포이드의 반환 유형을 갖는 함수입니다(비포이드의 경우에도).Void
는 값을 반환해야 합니다., , 태, 태, 태, methods, methods, methods, methods에 추가할 수 있다에 추가할 수 .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 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
'programing' 카테고리의 다른 글
휴지 상태: hbm2dl.auto=업데이트를 실가동 중입니까? (0) | 2022.07.12 |
---|---|
v-를 사용하여 개체 사용을 위한 선택 옵션 생성 (0) | 2022.07.12 |
매우 단순한 vue.display 컴포넌트가 최대 콜스택 크기를 초과했습니다. (0) | 2022.07.12 |
Tomcat 7에서 전쟁 파일을 배포하는 방법 (0) | 2022.07.12 |
Vuex 스토어가 이미 생성된 후 수동으로 Getter/mutation을 추가하는 방법 (0) | 2022.07.12 |