引入
何为匿名内部类?匿名内部类可以使你的代码更加简洁,你可以在定义一个类的同时对其进行实例化。它与局部类很相似,不同的是它没有类名,如果某个局部类你只需要用一次,那么你就可以使用匿名内部类。(摘自官方文档)
匿名内部类语法
实现接口的匿名类
我们都知道在给自定义对象集合排序的时候有两种方法。第一种是自定义类实现Comparable接口,重写compareTo方法。第二种是使用Comparator接口:编写多个排序方式类实现Comparator接口,并重写新Comparator接口中的compare()方法。如果我们在排序的时候只用一次定义的规则,就没有必要定义比较类,可直接使用匿名内部类。下面我们举个例子
public class demo_student {
public static void main(String[] args) {
ArrayList<student> al = new ArrayList<>();
al.add(new student("李四", 21));
al.add(new student("张三", 25));
al.add(new student("王五", 18));
al.add(new student("赵六", 13));
Comp comp = new Comp(); //创建比较规则类的对象
al.sort(comp);
al.sort(new Comparator<student>() { //使用匿名内部类写比较规则,根据学生年龄从小到大排序
@Override
public int compare(student o1, student o2) {
return o1.getAge() - o2.getAge();
}
});
al.forEach(student -> System.out.println(student.getName() + student.getAge()));
}
}
}
class Comp implements Comparator<student> {
@Override
public int compare(student o1, student o2) {
return o1.getAge() - o2.getAge();
}
}
public class student {
private String Name;
private int Age;
public student() {
}
public student(String Name, int Age) {
this.Name = Name;
this.Age = Age;
}
public void setName(String Name) {
this.Name = Name;
}
public void setAge(int Age) {
this.Age = Age;
}
public String getName() {
return this.Name;
}
public int getAge() {
return this.Age;
}
}
访问作用域内的局部变量、定义和访问匿名内部类成员
匿名内部类与局部类对作用域内的变量拥有相同的的访问权限。
(1)、匿名内部类可以访问外部内的所有成员;
(2)、匿名内部类不能访问外部类未加final修饰的变量(JDK1.8即使没有用final修饰也可以访问,因为底层已经加了final,详见可查看源码);
(3)、属性屏蔽,与内嵌类相同,匿名内部类定义的类型(如变量)会屏蔽其作用域范围内的其他同名类型(变量):
与lambda表达式和方法引用的关系
lambda表达式和方法引用一定可以改成匿名内部类而匿名内部类不都可以简化成lambda表达式和方法引用
通常方法引用优先于lambda表达式,lambda表达式优先于匿名类。带有单个抽象方法的接口称作为函数类型。他们的实例称为函数对象。故这样的接口优先使用lambda或方法引用。这样可以使程序的可读性提高且更加简洁。
public static void main(String[] args) {
ArrayList<student> al = new ArrayList<>();
al.add(new student("李四", 21));
al.add(new student("张三", 25));
al.add(new student("王五", 18));
al.add(new student("赵六", 13));
al.sort(Comparator.comparing(student::getAge)); //引用对象方法
al.sort(Comparator.comparing(student -> student.getAge())); //使用lambda表达式
al.forEach(student -> System.out.println(student.getName() + student.getAge()));
}
写在最后
以上是自己对匿名内部类的理解和一些总结。一般在事件处理、线程用的比较多。有些地方表达得不准确或是不清楚还希望读者能够指正。