Это вообще возможно?
Ответы:
если вы имеете в виду анонимную функцию и используете версию 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!"
Сам по себе это не очень полезно, но показывает, как создать экземпляр анонимного внутреннего класса, который 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 по определенному условию. Для этого вы можете использовать файл 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);
Для получения более подробной информации см. Руководство по лямбда-выражениям.
Анонимные внутренние классы, реализующие или расширяющие интерфейс существующего типа, были выполнены в других ответах, хотя стоит отметить, что можно реализовать несколько методов (часто, например, с событиями в стиле 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-документации, чтобы узнать, как мы можем объявлять анонимные функции, классы.
В следующем примере 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.
Круглые скобки, которые содержат аргументы конструктора, как и обычное выражение создания экземпляра класса. Примечание. Когда вы реализуете интерфейс, конструктора нет, поэтому вы используете пустую пару круглых скобок, как в этом примере.
Тело, которое является телом объявления класса. В частности, в теле объявления методов разрешены, а операторы - нет.