Це взагалі можливо?
Відповіді:
якщо ви маєте на увазі анонімну функцію і використовуєте версію Java перед Java 8, то одним словом, ні. ( Прочитайте про лямбда-вирази, якщо ви використовуєте 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!"
Це не дуже корисно, але воно показує, як створити екземпляр анонімного внутрішнього класу that 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і я хочу відфільтрувати Alphas за певною умовою. Для цього ви можете використовувати a Predicate<Alpha>. Це функціональний інтерфейс, який має метод, testякий приймає Alphaі повертає a 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 Expressions
Анонімні внутрішні класи, що реалізують або розширюють інтерфейс існуючого типу, були зроблені в інших відповідях, хоча варто зауважити, що можуть бути реалізовані кілька методів (часто, наприклад, з подіями в стилі 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методі. Скажи НІ перехоплюючі «неявно final» місцеві жителі? )
nodeслід оголосити finalтут.
cur.
"Node" +щоб зробити другий метод необхідним). / У мене немає імені. Можливо, я міг би створити запитання про "опитування" (CW), і проголосувати його забуваючи.
Так, якщо ви використовуєте останню java, яка є версією 8. Java8 надає можливість визначати анонімні функції, що було неможливо в попередніх версіях.
Давайте візьмемо приклад з java docs, щоб дізнатись, як ми можемо оголосити анонімні функції, класи
Наступний приклад, 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.
Дужки, які містять аргументи конструктора, як і звичайний вираз створення екземпляра класу. Примітка: Коли ви реалізуєте інтерфейс, конструктор відсутній, тому ви використовуєте порожню пару дужок, як у цьому прикладі.
Тіло, яке є тілом оголошення класу. Більш конкретно, в тілі декларації методів дозволені, а оператори - ні.