匿名内部类一般用在接口中,因为接口只包含常量和抽象方法,而如果某方法需要根据具体情况执行不同的操作,且使用不频繁的话,就可以用匿名内部类来完成。当然,抽象类以及一般类也可以使用匿名内部类。
一般类中使用匿名内部类的常用情况:
- 父类的构造函数是protected修饰的,在别的包中只能由继承关系的子类去调用构造方法,此时就可以调用匿名内部类,创建对象并调用方法,例如
new TypeToken<Map<String,User>>(){}.getType();
本来TypeToken有getType方法,但是在别的包中直接不能调用构造函数,所以使用匿名内部类,由子类去调用父类的构造函数,创建对象并调用getType方法
public interface Work { public void dowork(); }
假设有这么一个接口,里面有一个抽象方法dowork,如果想要调用该方法,需要先创建一个类,实现Work接口中的dowork方法。所以一般做法如下:
public class MyWork implements Work { @Override public void dowork() { // TODO Auto-generated method stub System.out.println("MyWork"); } }
创建一个类,用来实现接口。下面调用一下该方法:得到如下结果:public class Test { public static void main(String[] args) { Work work = new MyWork(); System.out.println(work); work.dowork(); } }
子类有类名,叫MyWork,而且也调用了dowork方法了。com.luke.test.noNameClass.MyWork@6d4b473 MyWork
使用匿名内部类调用:
也是多态,父类的引用指向子类的实例,所以w是一个引用,而以上就是通过匿名内部类创建了一个子类的实例对象,输出结果如下:public class Test { public static void main(String[] args) { Work w = new Work() { @Override public void dowork() { System.out.println("test"); } }; System.out.println(w); } }
此时子类是没有名字的,因为没有创建一个Class xx implements Work,所以是匿名。com.luke.test.noNameClass.Test$1@456d3d51
而且匿名内部类是创建了一个子类的实例,当然可以调用方法:
直接调用dowork方法,得到结果如下:public class Test { public static void main(String[] args) { new Work() { @Override public void dowork() { System.out.println("test"); } }.dowork(); } }
test
所以,所谓匿名内部类就是不用创建一个类去implements 接口或者extends 父类,直接创建子类实例,只不过没有子类的名字。