我怎样才能在Java中编写一个匿名函数?

这甚至有可能吗?

如果你的意思是一个匿名函数, 并且正在使用Java 8之前的Java版本,那么总之,不。 ( 如果您使用Java 8+,请阅读lambdaexpression式 )

不过,你可以用一个如下的函数实现一个接口:

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!" 

这并不是很有用,但它展示了如何创build一个extends Object的匿名内部类的实例和@OverridetoString()方法。

也可以看看

  • JLS 15.9.5匿名类声明

当你需要实现一个可能不是高度可重用的interface (因此不值得重构它自己命名的类)时,匿名内部类非常方便。 一个有启发性的例子是使用自定义的java.util.Comparator<T>进行sorting。

下面是一个如何基于String.length()String[]进行sorting的示例。

 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长度的情况)。

也可以看看

  • Java整数:什么是更快的比较或减法?
    • 一般来说,减法比较是被打破
  • 使用自定义比较器在Java中创buildsorting哈希
  • Java中如何使用匿名(内部)类?

随着Java 8中的lambdaexpression式的引入,您现在可以使用匿名方法。

假设我有一个Alpha类,我想在特定条件下过滤Alpha 。 要做到这一点,你可以使用Predicate<Alpha> 。 这是一个function接口,它有一个方法test ,接受一个Alpha并返回一个boolean

假设过滤方法有这个签名:

 List<Alpha> filter(Predicate<Alpha> filterPredicate) 

与旧的匿名类解决scheme,你需要像这样的东西:

 filter(new Predicate<Alpha>() { boolean test(Alpha alpha) { return alpha.centauri > 1; } }); 

有了Java 8 lambda,你可以这样做:

 filter(alpha -> alpha.centauri > 1); 

有关更多详细信息,请参阅Lambdaexpression式教程

实现或扩展现有types接口的匿名内部类已经在其他答案中完成了,不过值得注意的是可以实现多个方法(通常使用JavaBean风格的事件)。

有一点公认的特点是,尽pipe匿名内部类没有名字,但它们确实有一个types。 新的方法可以添加到接口。 这些方法只能在有限的情况下调用。 主要直接在newexpression本身和课堂内(包括实例初始化者)。 这可能会混淆初学者,但它可能是recursion“有趣的”。

 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而不是在print方式中写的, 说“否”来捕捉“隐式final ”的本地人?

是的,如果你使用的是最新版本的java。Java8可以定义匿名函数,这在以前的版本中是不可能的。

让我们从java文档中学习例子,以了解如何声明匿名函数,类

下面的示例HelloWorldAnonymousClasses在局部variablesfrenchGreeting和spanishGreeting的初始化语句中使用匿名类,但使用本地类来初始化variablesenglishGreeting:

 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(); } } 

匿名类的语法

考虑法国的对象的实例:

  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); } }; 

匿名类expression式由以下内容组成:

  • new运营商
  • 要实现的接口的名称或要扩展的类。 在这个例子中,匿名类正在实现接口HelloWorld。

  • 包含构造函数参数的括号,就像普通的类实例创buildexpression式一样。 注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,就像这个例子。

  • 一个机构,这是一个类声明机构。 更具体地说,在主体中,方法声明是允许的,但声明不是。