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