美文网首页
匿名内部类

匿名内部类

作者: 黄二的NPE | 来源:发表于2018-05-30 23:38 被阅读4次
  • 匿名内部类是什么?

引子
public abstract class Animal {
    abstract void sayHello();
}

假如现在有一个Animal的抽象类,他有一个sayHello的抽象方法.在我们的程序中,有时候我们需要一只猫,并且让它们sayHello,这时我们会新建一个Cat类,继承Animal,然后实现sayHello,比如

public class Cat extends Animal {
    @Override
    void sayHello() {
        System.out.println("hello, I am a cat");
    }
}

但是这时候如果我们又需要一只狗,怎么办?当然是新建一个Dog类,继承Animal,然后实现sayHello,比如

public class Dog extends Animal{

    @Override 
    void sayHello() {
        System.out.println("hello, I am a dog");
    }
}

接着,我们又需要鸡鸭鹅,我们又得新建鸡鸭鹅类,继承Animal,然后实现sayHello,但是我们新建的这些子类,很多都是只用到一次,然后就不会再用到了,这时我们会感觉新建类这种操作是比较麻烦的,而且时间久了,那些类会越来越多,那有没有更简便的方法呢?有的,那就是匿名内部类.我们来看看用匿名内部类来实现一只猫是怎么样的?

public class AnimalTest {
    public static void main(String[] args) {
        Animal cat = new Animal() {
            @Override 
            void sayHello() {
                System.out.println("hello, I am a cat");
            }
        };
    }
}

对比新建类的方式,用匿名内部类的方式显然更加简单优雅一点,我们若要执行sayHello的方法,只需要cat.sayHello()即可.

匿名内部类的实现方式

除了上面实现一个抽象类和抽象方法,匿名内部类还可以是实现一个接口类和接口方法,比如

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("I am " + Thread.currentThread().getName());
            }
        };
        Thread t = new Thread(r);
        t.start();

你打开Runnable一看,就知道原来Runnable是一个接口类

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
匿名

之所以叫做匿名,我感觉应该是它不像我们的猫狗鸡鸭鹅一样,有自己的类名,匿名内部类用的是抽象类的类名和接口名

内部类

之所以说是内部类,是因为他不用新建一个类,而是写在方法里面.

  • 匿名内部类的原理

public class AnimalTest {
    public static void main(String[] args) {
        final Integer age = 3;
        Animal cat = new Animal() {
            @Override
            void sayHello() {
                System.out.println("I am a cat, age = " + age);
            }
        };
        cat.sayHello();
    }
}

我们把该段代码编译以后,实际上是生成两个文件


编码后的文件

查看AnimalTest$1.class

package anonymous;
final class AnimalTest$1 extends Animal {
    AnimalTest$1(Integer var1) {
        this.val$age = var1;
    }
    void sayHello() {
        System.out.println("I am a cat, age = " + this.val$age);
    }
}

再查看AnimalTest.class

package anonymous;
import anonymous.AnimalTest.1;
public class AnimalTest {
    public AnimalTest() {
    }
    public static void main(String[] args) {
        Integer age = Integer.valueOf(3);
        Animal cat = new 1(age);
        cat.sayHello();
    }
}

变异后实际上偷偷生成一个animal的子类,在AnimalTest的主方法中,只是创建一个这个子类的对象.

为什么要用final

我们发现在匿名内部类中使用内名内部类外面的局部变量,必须要把局部变量修饰成final,这是为什么呢?
我们看上面的代码,会发现局部变量是通过构造函数传进匿名内部类中的,而且匿名内部类中使用的并不是这个局部变量本身,而是它的一个副本.这样子就会产生一个问题,如果我们在匿名内部类中修改局部变量的值,实际上并不是修改匿名内部类外面的局部变量的值,这时候就会产生数据不同步的情况.为了避免这种情况的发生,干脆把局部变量修饰成final,不可修改.

  • 什么时候可以用到匿名内部类?

同样的某些接口或者抽象方法的具体实现在程序中只会用到一次,就可以用匿名内部类.比如我们在程序中某个地方需要新建一个线程去处理把某个特定的缓存清除掉,注意整个程序只有一个地方会用到这个清除某个特定缓存的操作,或者其它地方需要清除的是其他不同的缓存

        Thread t = new Thread(){
            @Override
            public void run(){
                CacheUtil.remove(CACHE_ONE);
            }
        };
        t.start();

假如同样的某些接口或者抽象方法的具体实现在程序中只会用到多次,就是说上面的操作还有其他很多地方都会用到,这时候我们就可以新建一个Thread内,实现run方法.比如

public class CacheThread extends Thread {
    @Override
    public void run() {
        CacheUtil.remove(CACHE_ONE);
    }
}

相关文章

  • 内部类

    成员内部类 局部内部类(定义在方法内和定义在作用域内的类) 匿名内部类

  • Java匿名内部类

    导语 学完匿名内部类就懂的情书。 主要内容 接口与抽象类和匿名内部类的关系 具体内容 匿名内部类也就是没有名字的内...

  • java中的匿名内部类总结

    匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内...

  • Java 内部类

    内部类包括成员内部类、方法内部类、*静态内部类、匿名内部类*。 内部类的作用 由于内部类的实现和外部类没有关系,内...

  • 技术问 - 匿名内部类

    匿名内部类 匿名内部类的格式 匿名内部类的本质是什么? 代码: 匿名内部类在开发中使用: 看结果写代码

  • Java 内部类、静态内部类、方法内部类(未完待续)

    内部类 什么是内部类?内部类其实就是在一个类中创建的类。内部类有四种: 成员内部类 静态内部类 局部内部类 匿名内...

  • Android菜鸟起飞|三种方法实现监听事件

    Android实现监听事件的三种方式(匿名内部内实现,外部类实现,接口实现)详解 1. 使用匿名内部类的方式实现监...

  • java 内部类

    一般有四种内部类的使用方式: 嵌套的内部类 方法内的内部类 静态内部类 匿名内部类 什么时候用内部类: 有时候明显...

  • Java 内部类

    1. 内部类 概念:在一个类的内部再定义一个完整的类内部类分为 4 类:成员内部类、静态内部类、局部内部类、匿名内...

  • 详解匿名内部类【Java提高九】

    在这篇博客中你可以了解到匿名内部类的使用、匿名内部类要注意的事项、如何初始化匿名内部类、匿名内部类使用的形参为何要...

网友评论

      本文标题:匿名内部类

      本文链接:https://www.haomeiwen.com/subject/nzrojftx.html