, если вы имеете в виду анонимную функцию, и используют версию 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!"
Это не очень полезно, но показывает, как создать экземпляр анонимного внутреннего класса, который расширяет Object
и @Override
его toString()
метод.
Анонимные внутренние классы очень удобны, когда вам нужно реализовать интерфейс
, который может оказаться малопригодным для повторного использования (и поэтому его не стоит рефакторить в собственный именованный класс). Поучительным примером является использование пользовательского java.util.Comparator
для сортировки.
Вот пример того, как можно отсортировать 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
).
Анонимные внутренние классы, реализующие или расширяющие интерфейс существующего типа, были выполнены в других ответах, хотя стоит отметить, что могут быть реализованы несколько методов (часто с событиями в стиле 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
. Сказать НЕТ захвату «неявно окончательных
» местных жителей? )