专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java匿名内部类的概念

Java匿名内部类的概念

更新时间:2022-12-21 12:29:23 来源:动力节点 浏览936次

匿名类是没有名称的本地类。使用new运算符在一个简洁的表达式中定义和实例化匿名类。本地类定义是 Java 代码块中的一条语句,而匿名类定义是一个表达式,这意味着它可以作为更大表达式(例如方法调用)的一部分包含在内。当一个本地类只被使用一次时,考虑使用匿名类语法,它将类的定义和使用放在完全相同的地方。

用匿名类实现的枚举

公共 java.util.Enumeration 枚举(){
  // 匿名类被定义为返回语句的一部分
  返回新的 java.util.Enumeration() {
    可连接电流;= 头;
    { 当前 = 头; } // 用实例初始化器替换构造函数
    public boolean hasMoreElements() { return (current != null); }
    公共对象 nextElement() {
      if (current == null) throw new java.util.NoSuchElementException();
      对象值=当前;
      current = current.getNext();
      返回值;
    }
  }; // 注意所需的分号:它终止返回语句
}

匿名类的一个常见用途是提供适配器类的简单实现。适配器类是定义由其他某个对象调用的代码的类。以java.io.File类的list()方法 为例。此方法列出目录中的文件。不过,在返回列表之前,它会将每个文件的名称传递给您必须提供的FilenameFilter对象。此FilenameFilter对象接受或拒绝每个文件。当您实现 FilenameFilter接口时,您正在定义一个适配器类以与File.list()一起使用方法。由于此类的主体通常很短,因此很容易将适配器类定义为匿名类。以下是如何定义FilenameFilter类以仅列出名称以.java 结尾的那些文件:

文件 f = 新文件("/src"); // 要列出的目录
// 现在用一个 FilenameFilter 参数调用 list() 方法
// 定义并实例化 FilenameFilter 的匿名实现
// 作为方法调用表达式的一部分。
String[] filelist = f.list(new FilenameFilter() {
  public boolean accept(File f, String s) { return s.endsWith(".java"); }
}); // 不要忘记结束方法调用的括号和分号!

如您所见,定义匿名类和创建该类实例的语法使用new关键字,后跟类名和花括号中的类主体定义。如果new关键字后面的名称是类的名称,则匿名类是命名类的子类。如果new后面的名称指定了一个接口,如前两个示例所示,匿名类将实现该接口并扩展Object。该语法不包括任何指定 扩展子句、 实现子句或类名称的方法。

因为匿名类没有名称,所以不可能在类主体中为它定义构造函数。这是对匿名类的基本限制之一。您在匿名类定义中超类名称后的括号中指定的任何参数都隐式传递给超类构造函数。匿名类通常用于子类化不带任何构造函数参数的简单类,因此匿名类定义语法中的括号通常为空。在前面的示例中,每个匿名类都实现了一个接口并扩展了Object。由于Object()构造函数不带参数,因此这些示例中的括号为空。

匿名类的特点

关于匿名类的最优雅的事情之一是它们允许您在需要的地方准确地定义一次性类。此外,匿名类的语法简洁,可以减少代码中的混乱。

匿名类的限制

因为匿名类只是本地类的一种,所以匿名类和本地类具有相同的限制。匿名类不能定义任何静态字段、方法或类,静态最终 常量除外。接口不能匿名定义,因为没有名字就无法实现接口。此外,与本地类一样,匿名类不能是 public、private、 protected或static。

由于匿名类没有名称,因此不可能为匿名类定义构造函数。如果您的类需要构造函数,则必须改用本地类。但是,您通常可以使用实例初始值设定项来替代构造函数。事实上,正是出于这个目的,将实例初始化程序引入了该语言。

定义匿名类的语法结合了定义和实例化。因此,如果每次执行包含块时都需要创建该类的多个实例,则使用匿名类而不是本地类是不合适的。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>