匿名内部类可以看作是特殊的局部内部类,其本质就是一个继承类(或实现接口)的匿名子类。
匿名内部类是在使用的时候动态的指定方法体的逻辑,无需每次都去创建一个继承类(或实现接口)的子类。编译器会在编译阶段自动生成一个匿名子类。
匿名内部类的语法格式:new 接口名|类名(){重写方法}
其中,如果重写方法为非必要的,原则上是可以没有重写方法部分的。
父子类:
public class ParentClass {
public void aa(String str) {
}
public void bb(String str) {
}
}
public class ChildClass extends ParentClass {
@Override
public void aa(String str) {
System.out.println("自定义方法体");
}
@Override
public void bb(String str) {
System.out.println("自定义方法体");
}
}
public class Test {
public static void main(String[] args) {
ParentClass ohj = new ChildClass();
}
}
接口实现类:
public interface ParentInterface {
void aa(String str);
void bb(String str);
}
public class ChildClass implements ParentInterface {
@Override
public void aa(String str) {
System.out.println("自定义方法体");
}
@Override
public void bb(String str) {
System.out.println("自定义方法体");
}
}
public class Test {
public static void main(String[] args) {
ParentInterface ohj = new ChildClass();
}
}
父子类:
public class ParentClass {
public void aa(String str) {
}
public void bb(String str) {
}
}
public class Test {
public static void main(String[] args) {
ParentClass obj = new ParentClass() {
@Override
public void aa() {
System.out.println("自定义方法体");
}
@Override
public void bb() {
System.out.println("自定义方法体");
}
};
}
}
接口实现类:
public interface ParentInterface {
void aa(String str);
void bb(String str);
}
public class Test {
public static void main(String[] args) {
ParentInterface obj = new ParentInterface() {
@Override
public void aa() {
System.out.println("自定义方法体");
}
@Override
public void bb() {
System.out.println("自定义方法体");
}
};
}
}
从Java8开始,引入了Lambda表达式。
对于只有一个抽象方法的接口(函数式接口),可以直接使用Lambda表达式创建它的匿名实现类实例。
Lambda表达式的语法格式:(参数列表) -> {方法体}
省略写法:
public interface ParentInterface {
void aa(String str);
}
public class Test {
public static void main(String[] args) {
ParentInterface obj = new ParentInterface() {
@Override
public void aa(String str) {
System.out.println("自定义方法体");
}
};
}
}
public class Test {
public static void main(String[] args) {
ParentInterface obj = str -> System.out.println("自定义方法体");
}
}
方法引用是对Lambda表达式进一步简化,借用其他类的方法体,省去了写方法体的过程。
对于方法体只有一行代码的Lambda表达式(该行代码为调用某个类或某个实例的方法时),可以简洁为更简单的方法引用的方式。
方法引用的语法格式:
语法种类 | 语法格式 | 示例 | 参数对应关系 |
---|---|---|---|
类型的静态方法引用 | 类::静态方法 | String::valueOf | 抽象方法的参数与静态方法的参数顺序对应 |
类型的构造方法引用 | 类::new | String::new | 抽象方法的参数与构造方法的参数顺序对应 |
类型的实例方法引用 | 类::实例方法 | String::replaceAll | 抽象方法的第一个参数为调用引用方法的实例对象 抽象方法的剩余参数与实例方法的参数顺序对应 |
对象的实例方法引用 | 对象::实例方法 | s::replaceAll | 实例对象s为外部参数 抽象方法的参数与实例方法的参数顺序对应 |
需要注意:
类型的静态方法引用:类名::静态方法
对应Lambda表达式:(参数1,参数2,…) -> 类名.静态方法(参数1,参数2,…)
@FunctionalInterface
public interface ParentInterface {
String aa(String s);
}
public class Test {
public static void main(String[] args) {
// 类型的静态方法引用
ParentInterface parentInterface1 = String::valueOf;
// 对应Lambda表达式方式
ParentInterface parentInterface2 = s -> String.valueOf(s);
}
}
类型的构造方法引用:类::new
对应Lambda表达式:(参数1,参数2,…) -> new 类名(参数1,参数2,…)
@FunctionalInterface
public interface ParentInterface {
String aa(String s);
}
public class Test {
public static void main(String[] args) {
// 类型的构造方法引用
ParentInterface parentInterface1 = String::new;
// 对应Lambda表达式方式
ParentInterface parentInterface2 = s -> new String(s);
}
}
类型的实例方法引用:类::实例方法
对应Lambda表达式:(参数1,参数2,…) -> 参数1.静态方法(参数2,…)
@FunctionalInterface
public interface ParentInterface {
String aa(String s1, String s2, String s3);
}
public class Test {
public static void main(String[] args) {
// 类型的实例方法引用
ParentInterface parentInterface1 = String::replaceAll;
// 对应Lambda表达式方式
ParentInterface parentInterface2 = (s1,s2,s3) -> s1.replaceAll(s2,s3);
}
}
对象的实例方法引用:对象::实例方法
对应Lambda表达式:(参数1,参数2,…) -> 对象.静态方法(参数1,参数2,…)
@FunctionalInterface
public interface ParentInterface {
String aa(String s1, String s2);
}
public class Test {
public static void main(String[] args) {
String s = "";
// 对象的实例方法引用
ParentInterface parentInterface1 = s::replaceAll;
// 对应Lambda表达式方式
ParentInterface parentInterface2 = (s1,s2) -> s.replaceAll(s1,s2);
}
}