可能吗
Answers:
如果您的意思是匿名函数,并且在Java 8之前使用的是Java版本,那么总而言之,不是。(如果您使用Java 8+,请阅读有关lambda表达式的信息)
但是,您可以使用以下功能实现接口:
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中引入lambda表达式,您现在可以拥有匿名方法。
假设我有一个课程,Alpha
并且想Alpha
在特定条件下过滤。为此,您可以使用Predicate<Alpha>
。这是一个功能性接口,具有一个test
接受anAlpha
并返回an的方法boolean
。
假设filter方法具有以下签名:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
使用旧的匿名类解决方案,您将需要执行以下操作:
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
使用Java 8 lambda,您可以执行以下操作:
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)问题,并将其淘汰。
是的,如果您使用的是版本8的最新Java。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。
括号中包含构造函数的参数,就像普通的类实例创建表达式一样。注意:在实现接口时,没有构造函数,因此,如本例所示,使用一对空括号。
一个主体,它是一个类声明主体。更具体地说,在主体中,允许使用方法声明,但不允许使用语句。