Java匿名内部类详解

关于匿名内部类首先要明白:

1,匿名内部类是定义在类的局部位置的(方法或者代码块中)

2,匿名内部类可以理解为一个类同时也是一个对象

3,匿名内部类没有类名(其实还是有类名的,一会看代码演示)

4,基本语法:new 接口或者类(参数列表){

                       类体

};

下面来看看基于一个接口的匿名内部类,先看一段代码:

public class Outer {
    public void f(){
        IA ia = new IA(){
            @Override
            public void say() {
                System.out.println("hi~");
            }
        };
        ia.say();
    }
}

interface IA{
    void say();
}

class test21{
    public static void main(String[] args) {
        new Outer().f();
    }
}

关于这段代码肯定有很多疑问,我来一一解释一下。

先来看一个需求:我有一个接口,现在我想要实现接口里面的方法,并且在Outer类的f()方法里去使用这个方法。

常规的方法就是写一个新的类,让这个类去实现这个接口,然后再new一个对象,通过对象去调用这个方法。可是如果我这个方法只用一次的话,这样去做就显的代码有一些啰嗦,如果再来一个接口就又要写一个新的类......,这样想想都烦。所以我们就可以使用匿名内部类去解决这个问题。

所以上面这段代码就可以这样理解:

IA ia = new IA(){}

这里肯定有很多疑问,为什么可以实例化一个接口?其实这里不是实例化一个接口,这里在底层就相当于系统去创建了一个实现了IA接口的类(也就是匿名内部类),然后立马去创建了这个类的对象,接着返回给ia,让ia去指向这个对象,最后要注意,底层在创建了一个对象之后,这个类就没有了(不是说ia没有了,只是匿名内部类没有了,但是返回的对象还是存在的)。

这就是匿名内部类的一个大体过程,那我为什么说匿名内部类其实是有名字的呢,其实只要调一下ia的getclass方法就可以很清楚的看到底层创建的匿名内部类的名字了?下面看一段代码:

public class Outer {
    public void f(){
        IA ia = new IA(){
            @Override
            public void say() {
                System.out.println("hi~");
            }
        };
        System.out.println(ia.getClass());
    }
}

interface IA{
    void say();
}

class test21{
    public static void main(String[] args) {
        new Outer().f();
    }
}

输出结果:class Outer$1

所以这个Outer$1就是匿名内部类的名字,这也就证实了我前面说的匿名内部类其实是有名字的。

再来看看基于一个类的匿名内部类:

public class Outer {
    public void f(){
        M m =new M(){
            @Override
            public void say() {
                System.out.println("hello");
            }
        };
        m.say();
    }
}

class M{
    public void say(){
        System.out.println("hi");
    }
}

class test21{
    public static void main(String[] args) {
        new Outer().f();
    }
}

如果前面的东西已经理解了,相信这里大家都应该猜到了基于一个类的匿名内部类的大体过程了。没错,底层就是创建了一个继承了M类的类(也是就匿名内部类),然后再new一个匿名内部类的对象,最后再返回给m。

可以思考一下这段代码会输出上面结果

输出的结果其实是hello,这应该也不难,如果弄明白了过程就可以知道,这里面其实是有一个向上转型的过程的,因为m的编译类型是M而运行类型是......注意这里可不是什么M了,而是匿名内部类Outer$1(这个可以自己输出看一下)而Outer$1又是M的子类,用父类的引用去指向子类的对象。这可不就是典型的向上转型嘛,所以输出的自然就是hello了。

还有基于抽象类的匿名内部类,我就不再详细说明了,相信大家已经很清楚了。

这里主要就是为大家讲解了一下匿名内部类的底层运行过程,还有其他简单的细节可能还没有讲到,但是那些都是跟局部内部类是差不多的东西了,如果大家有什么不理解的地方,欢迎私信询问我,如果文章有什么错误,欢迎大家评论区指正。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值