가능할까요?
답변:
익명 기능을 의미하고 Java 8 이전의 Java 버전을 사용하는 경우 한마디로 아닙니다. ( Java 8 이상을 사용하는 경우 람다 식에 대해 읽어보십시오 )
그러나 다음과 같은 함수로 인터페이스를 구현할 수 있습니다.
Comparator<String> c = new Comparator<String>() {
int compare(String s, String s2) { ... }
};
그리고 이것을 내부 클래스와 함께 사용하여 거의 익명의 함수를 얻을 수 있습니다. :)
다음은 익명 내부 클래스의 예입니다.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
이것은 그다지 유용하지 않지만 익명의 내부 클래스 extends Object
와 @Override
그 toString()
메소드 의 인스턴스를 만드는 방법을 보여줍니다 .
익명 내부 클래스는 interface
재사용이 불가능할 수있는를 구현해야 할 때 매우 편리합니다 (따라서 자체 명명 된 클래스로 리팩토링 할 가치가 없습니다). 유익한 예는 java.util.Comparator<T>
정렬에 사용자 지정 을 사용하는 것 입니다.
를 String[]
기반 으로을 정렬하는 방법의 예는 다음과 같습니다 String.length()
.
import java.util.*;
//...
String[] arr = { "xxx", "cd", "ab", "z" };
Arrays.sort(arr, new Comparator<String>() {
@Override public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
System.out.println(Arrays.toString(arr));
// prints "[z, cd, ab, xxx]"
여기에 사용 된 뺄셈 비교 트릭에 유의하십시오. 이 기술은 일반적으로 깨 졌다고 말해야합니다. 오버플로되지 않을 것임을 보장 할 수있는 경우에만 적용됩니다 ( String
길이 가있는 경우 ).
EventListener
평균 Swing 애플리케이션에서 (하위) 구현 으로 찾을 수 있습니다 .
Linked
사이드 바를 추가 했으므로 최대한 활용하기 위해 최선을 다하고 있습니다.
Java 8에 람다식이 도입됨에 따라 이제 익명 메서드를 사용할 수 있습니다.
클래스가 Alpha
있고 Alpha
특정 조건에서 s 를 필터링하고 싶습니다 . 이를 위해 Predicate<Alpha>
. test
이것은를 받아들이고 Alpha
를 반환하는 메서드가있는 기능적 인터페이스입니다 boolean
.
필터 메서드에 다음 서명이 있다고 가정합니다.
List<Alpha> filter(Predicate<Alpha> filterPredicate)
이전 익명 클래스 솔루션을 사용하면 다음과 같은 것이 필요합니다.
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
Java 8 람다로 다음을 수행 할 수 있습니다.
filter(alpha -> alpha.centauri > 1);
자세한 내용은 Lambda 표현식 자습서를 참조하십시오.
기존 유형의 인터페이스를 구현하거나 확장하는 익명의 내부 클래스는 다른 답변에서 수행되었지만 여러 메서드를 구현할 수 있다는 점은 주목할 가치가 있습니다 (예 : JavaBean 스타일 이벤트).
약간 인식 된 기능은 익명의 내부 클래스에는 이름이 없지만 유형이 있다는 것입니다. 인터페이스에 새 메소드를 추가 할 수 있습니다. 이러한 메서드는 제한된 경우에만 호출 할 수 있습니다. 주로 new
표현식 자체 및 클래스 내 (인스턴스 이니셜 라이저 포함)에 직접. 초보자에게는 혼란 스러울 수 있지만 재귀에 대해서는 "흥미 롭다".
private static String pretty(Node node) {
return "Node: " + new Object() {
String print(Node cur) {
return cur.isTerminal() ?
cur.name() :
("("+print(cur.left())+":"+print(cur.right())+")");
}
}.print(node);
}
(나는 원래 사용하여이 쓴 node
것이 아니라 cur
의 print
방법. 말 NO "를 암시 적으로 캡처에 final
"지역 주민을? )
node
final
여기서 선언해야합니다 .
cur
.
"Node" +
두 번째 메서드를 필요로하는 것과 약간 관련 이 없음). / 이름이 없어요. 아마도 CW (nameming "poll") 질문을 만들어 망각에 빠뜨릴 수있을 것입니다.
예, 버전 8 인 최신 자바를 사용하는 경우 가능합니다. Java8을 사용하면 이전 버전에서는 불가능했던 익명 함수를 정의 할 수 있습니다.
익명 함수, 클래스를 선언하는 방법을 알기 위해 Java 문서 에서 예제 를 가져옵니다.
다음 예제 HelloWorldAnonymousClasses는 로컬 변수 frenchGreeting 및 spanishGreeting의 초기화 문에서 익명 클래스를 사용하지만 변수 englishGreeting의 초기화에는 로컬 클래스를 사용합니다.
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
HelloWorld spanishGreeting = new HelloWorld() {
String name = "mundo";
public void greet() {
greetSomeone("mundo");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
익명 클래스의 구문
frenchGreeting 객체의 인스턴스화를 고려하십시오.
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
익명 클래스 표현식은 다음으로 구성됩니다.
new
연산자구현할 인터페이스 또는 확장 할 클래스의 이름입니다. 이 예제에서 익명 클래스는 HelloWorld 인터페이스를 구현합니다.
일반 클래스 인스턴스 생성 표현식과 마찬가지로 생성자에 대한 인수를 포함하는 괄호. 참고 : 인터페이스를 구현할 때 생성자가 없으므로이 예제에서와 같이 빈 괄호 쌍을 사용합니다.
클래스 선언 본문 인 본문입니다. 보다 구체적으로 본문에서 메서드 선언은 허용되지만 문은 허용되지 않습니다.