Runnable :: new 대 new Runnable ()
다음 예제 중 첫 번째 작동 작동하지 않는 이유는 무엇입니까?
run(R::new);
메서드R.run
가 호출되지 않습니다.run(new R());
메서드R.run
가 호출됩니다.
두 예제 모두 모두 가능합니다.
public class ConstructorRefVsNew {
public static void main(String[] args) {
new ConstructorRefVsNew().run(R::new);
System.out.println("-----------------------");
new ConstructorRefVsNew().run(new R());
}
void run(Runnable r) {
r.run();
}
static class R implements Runnable {
R() {
System.out.println("R constructor runs");
}
@Override
public void run() {
System.out.println("R.run runs");
}
}
}
출력은 다음과 가변합니다.
R constructor runs
-----------------------
R constructor runs
R.run runs
첫 번째 예제에서는 R
생성자가 호출되고 람다 (객체가 아님)를 반환합니다.
어떤 방법이 예제가 사용으로 있습니까?
귀하의 run
메소드는 인스턴스를 취하며 구현 과 함께 작동하는 이유를 설명합니다 .Runnable
run(new R())
R
R::new
과 동일하지 않습니다 new R()
. Supplier<Runnable>
(또는 사용할 수없는 기능적 인터페이스) 의 서명에 함께 맞을 수 있고 클래스 와 구현 된 R::new
사용할 수 있습니다 .Runnable
R
run
수 사용할 R::new
있는 메서드 의 버전은 다음과 같을 수 있습니다 (하지만 불필요하게 복잡함).
void run(Supplier<Runnable> r) {
r.get().run();
}
왜 선택?
컴파일러가 생성자 호출을 외부로 만들 수 있기 때문에 람다 식 버전과 동일합니다.Runnable
new ConstructorRefVsNew().run(() -> {
new R(); //discarded result, but this is the run() body
});
다음 문에도 동일하게 적용됩니다.
Runnable runnable = () -> new R();
new ConstructorRefVsNew().run(runnable);
Runnable runnable2 = R::new;
new ConstructorRefVsNew().run(runnable2);
당신이 알 수 그러나,은으로 만든은 단지 전화 의 메소드 본문.Runnable
R::new
new R()
run
사용할 방법 참조의 유효한 사용은 다음 R#run
과 같이 인스턴스를 사용할 수 있습니다 (그러나이 경우에는 r
인스턴스를 직접 사용하는 것이 좋습니다 ).
R r = new R();
new ConstructorRefVsNew().run(r::run);
첫 번째 예 :
new ConstructorRefVsNew().run(R::new);
다음과 다소 동일합니다.
new ConstructorRefVsNew().run( () -> {new R();} );
결과는 R의 인스턴스를 생성하고 해당 run
메서드를 호출하지 않는 것입니다.
두 호출 비교 :
((Runnable)() -> new R()).run();
new R().run();
으로 ((Runnable)() -> new R())
또는 ((Runnable) R::new)
, 당신은 만들 새를Runnable
아무것도하지 않습니다 어떤 일을 .
으로는 new R()
, 당신은 생성 의 인스턴스 R
클래스run
방법은 잘 정의된다.
1 실제로 R
실행에 영향을 미치지 않는 객체를 생성합니다 .
main
방법 을 수정하지 않고 두 번의 호출을 동일하게 처리 할 생각이었습니다 . 우리는 오버로드 할 필요 run(Runnable)
와 함께 run(Supplier<Runnable>)
.
class ConstructorRefVsNew {
public static void main(String[] args) {
new ConstructorRefVsNew().run(R::new);
System.out.println("-----------------------");
new ConstructorRefVsNew().run(new R());
}
void run(Runnable r) {
r.run();
}
void run(Supplier<Runnable> s) {
run(s.get());
}
static class R implements Runnable { ... }
}
이 run
메서드는 Runnable
.
쉬운 경우는 new R()
입니다. 이 경우 결과가 유형의 객체임을 알고 있습니다 R
. R
그 자체는 실행 가능하고 run
메소드 가 있으며 Java가 보는 방식입니다.
그러나 통과하면 R::new
다른 일이 발생합니다. 당신이 말하는 것은 Runnable
누구의 run
메소드가 당신이 전달한 작업을 실행하는지 와 호환되는 익명의 객체를 만드는 것입니다.
전달한 작업은 R
의 run
방법 이 아닙니다 . 작업은의 공동 구조자입니다 R
. 따라서 다음과 같은 익명 클래스를 전달한 것과 같습니다.
new Runnable() {
public void run() {
new R();
}
}
(모든 세부 사항이 동일하지는 않지만 이것은 가장 가까운 "고전적인"Java 구조입니다).
R::new
을 호출하면 new R()
. 그 이상도 그 이하도 아닙니다.
참고 URL : https://stackoverflow.com/questions/54072359/runnablenew-vs-new-runnable
'ProgramingTip' 카테고리의 다른 글
SHA512에서 해시 된 길이는 얼마입니까? (0) | 2020.12.01 |
---|---|
Golang 메모리를 분석하는 방법? (0) | 2020.12.01 |
Java에서 기본 애플리케이션 아이콘을 어떻게 변경합니까? (0) | 2020.12.01 |
JSTL jar는 어디에서 다운로드 할 수 있습니까? (0) | 2020.12.01 |
ID, 클래스 및 요소 유형 접두사를 포함하는 HTML 명명 규칙? (0) | 2020.12.01 |