匿名内部类适合创建那些只需要使用一次的类,它的语法有些奇怪,创建匿名内部类会立即创建一个该类的实例,这个类定义立即消失,且不能重复使用。

定义匿名类的格式如下:

new 实现接口() |父类构造器(实参列表){
//匿名内部类的类体部分
}

从定义来看,匿名内部类必须继承一个父类,或者实现一个接口,但是最多只能继承一个父类或者实现一个接口。

关于匿名内部类,还有如下两条规则:

  1. 匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。
  2. 匿名内部类不能定义构造器。因为匿名内部类没有类名,所以无法定义构造器。但是匿名内部类可以定义初始化块,通过实例初始化块来完成构造器需要完成的事情。

下面给出了一个常见的匿名内部类的使用示例:

public class Main {
public static void main(String[] args){
Main main = new Main();
main.test(new Man(){
//这里传入一个Man接口的匿名实现类的实例
public void talk(){
System.out.print("I'm a man!");
//output I'm a man!
}
});
} public void test(Man m){
//调用该方法需要传入一个Man类型参数
m.talk();
}
} interface Man{
void talk();
}

定义一个匿名内部类无需使用class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。

由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的抽象方法。

虽然上面的例子完全可以采用使用实现类对象的方法来完成相同的功能,但是明显使用匿名内部类更加简洁。

当通过实现接口来创建匿名内部类时,匿名内部类不能显式创建构造器,因此匿名内部类只有一个隐式的无参数构造器,故new接口名后的括号中不能传入参数。

但是如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,注意此处相似的构造器指的是拥有相同形参列表。

下面是通过继承父类来创建匿名内部类的示例:

public class Main {
public static void main(String[] args){
Main main = new Main();
main.test(new Man("Amos H"){
//这里传入一个Man接口的匿名实现类的实例
public void talk(){
System.out.println(this.getName());
//output Amos H
}
public int getHight(){
return 175;
}
});
} public void test(Man m){
//调用该方法需要传入一个Man类型参数
m.talk();
}
} abstract class Man{
private String name;
public Man(String name){
this.name = name;
}
public void talk(){
System.out.println(name);
};
public String getName(){
return name;
}
public abstract int getHight();
}

可以看到,创造匿名内部类可以使用和父类相同的参数列表,调用父类的构造器。

当创建匿名内部类时,必须实现接口或者抽象父类中的所有抽象方法。如果有必要的话,可以重写父类中的普通方法。

内部类的二三事:

非静态内部类对象和外部类对象的关系如何?

非静态内部类对象必须寄生在外部类对象中,而外部类对象则不一定有非静态内部类对象寄生其中。因此外部类对象不能访问非静态内部类对象,而非静态内部类对象可以访问外部类成员,因为存在内部类必然存在外部类。

非静态内部类对象是否可以有静态初始化块?

非静态内部类对象不可以有静态初始化块,但是可以有普通初始化块。非静态内部类普通初始化块的作用与外部类初始化块的作用完全相同。

为何静态内部类的实例方法也不能访问外部类的实例属性?

因为静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。当静态内部类对象存在时,并不一定存在一个被它寄生的外部类对象,静态内部类对象只持有外部类的类引用,并没有持有外部类对象的引用。如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄生的外部类对象,这将引起错误。

如何实例化一个非静态内部类

非静态内部类的子类不一定是内部类,它也可以是一个外部类。但是非静态内部类的子类实例一样要保留一个引用,该引用用于指向其父类所在外部类的对象。也就是说,如果一个内部类子类的对象存在,则一定存在与之对应的外部类对象。因为要实例化一个非静态内部类的语法通常是这样的:

Out.In in = new Out().new In();

可以看到,非静态内部类的构造器必须使用外部类对象来调用。

Java中的匿名内部类及内部类的二三事的更多相关文章

  1. java中的几种内部类

    Java中的几种内部类 内部类,听名字就可以知道是什么意思,就是类里面的类.有成员内部类,静态内部类,局部内部类和匿名内部类. 下面说一个每种内部类的的使用. 一.  成员内部类

  2. java中的匿名内部类总结(转)

    源出处: java中的匿名内部类总结 匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接 ...

  3. java中的匿名内部类

    匿名内部类在java编码中不是很常见,它可一让类实现多继承的特性(多个父类~1个子类) java中的匿名内部类总结http://www.cnblogs.com/nerxious/archive/201 ...

  4. Java中使用google.zxing快捷生成二维码(附工具类源码)

    移动互联网时代,基于手机端的各种活动扫码和收付款码层出不穷:那我们如何在Java中生成自己想要的二维码呢?下面就来讲讲在Java开发中使用 google.zxing 生成二维码. 一般情况下,Java ...

  5. java中的四种内部类使用(1)

    内部类 (一) 概述 把类定义在另一个类的内部,该类就被称为内部类. 举例:把类Inner定义在类Outer中,类Inner就被称为内部类. class Outer { class Inner { } ...

  6. Java中的集合框架-Collection(二)

    上一篇<Java中的集合框架-Collection(一)>把Java集合框架中的Collection与List及其常用实现类的功能大致记录了一下,本篇接着记录Collection的另一个子 ...

  7. java中注解的使用与实例 (二)

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  8. java中常用的工具类(二)

    下面继续分享java中常用的一些工具类,希望给大家带来帮助! 1.FtpUtil           Java   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  9. 走进Java中的持有对象(容器类)【二】Collection

    概述 通过前文的学习,我们对容器的分类及常用容器类的作用有了基本的认识.本文将针对Collection容器的功能与使用进行细致分析. 基本操作 Collection集合抽象出的目的是为存放独立元素的序 ...

随机推荐

  1. configSections必须是根节点下第一个节点

    对webconfig文档进行配置,添加了一个节点configSectionS,添加时,我自个想,按节点的名称以字母排序,就放在appSettings节点下. 谁知,在程序运行时,出现了错误: 参考上面 ...

  2. 包建强的培训课程(10):Android插件化从入门到精通

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  3. 剑指offer面试题17:合并两个排序的链表

    题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点人是按照递增排序的.解题思路:两个链表分别都已经是有序的了,遍历链表的时候只要比较两个链表当前位置大小,取出最小的添加到新链表中. 可以有 ...

  4. MySQL 每秒 570000 的写入,如何实现?

    阅读本文大概需要 2.8 分钟. 来源:http://t.cn/E2TbCg5 一.需求 一个朋友接到一个需求,从大数据平台收到一个数据写入在20亿+,需要快速地加载到MySQL中,供第二天业务展示使 ...

  5. 微信小程序wx.request接口

    微信小程序wx.request接口 wx.request是小程序客户端与服务器端交互的接口 HTTPS 请求 一个微信小程序,只能同时(同时不能大于5个)有5个网络请求 wx.request(OBJE ...

  6. 第46节:Java当中的常量池

    Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区. 程序计数器是jvm执行程序的流水线,是用来存放一些指令的,本地方法栈是jvm操作系统方 ...

  7. kafka扫盲笔记,实战入门

    Kafka作为大数据时代的产物,自有其生存之道.让我们跟随扫盲班的培训,进行大致了解与使用kafka吧.(平时工作有使用不代表就知道kafka了哟) 1. kafka介绍 1.1. 拥有的能力(能干什 ...

  8. idea 过段时间java程序包不存在问题 ?

    有时候我们在导入程序之后,系统会给出错误提示:Java:程序包xxxx不存在,现在我这里有一招,就是使用IDEA自动导入Java程序包,这也是IDEA的一大优点. 但是在看到这个问题的文章的时候,并不 ...

  9. 8.python面向对象编程

    基本概念 Class 类一个类即是对一类拥有相同属性的对象的抽象.蓝图.原型.在类中定义了这些对象的都具备的属性(variables(data)).共同的方法 Object 对象 一个对象即是一个类的 ...

  10. php安装xunserch

    xunserch的安装步骤 注意:xunserch只能在linux下使用 1.安装依赖工具 yum install make gcc g++ gcc-c++ libtool autoconf auto ...