静态内部类
/**
* 静态成员是在类加载成字节码时就已经存在的,静态只能访问静态
*/
public class Demo {
public static void main(String[] args) {
Outer.Inner.show();
}
}
class Outer {
int num1 = 10;
static int num2 = 20;
static class Inner {
static void show() {
Outer outer = new Outer();
System.out.println(outer.num1);
System.out.println("show...");
System.out.println(num2);
}
}
}
局部内部类
/**
* 放在方法/代码块/构造器等执行体中
* 方法体内的类必须在方法被执行的情况下才能被创建
*/
public class LocalInnerClass {
public static void main(String[] args) {
A a = new A();
a.show();
}
}
class A {
void show() {
class B {
void show() {
System.out.println("show--inner");
}
}
B b = new B();
b.show();
}
}
匿名内部类
/**
* 匿名内部类:
* overview: 匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)
* prerequisite:需要存在一个接口或类
* syntax: new className\interfaceName(){}
* new className(){}:代表继承这个类
* new interfaceName(){}:代表实现这个接口
*/
public class AnonymousInnerClass {
public static void main(String[] args) {
//方法的形参是接口类型应该传入接口的实现类对象
useInter(new InterImpl());
useInter(new Inter() {
@Override
public void show() {
System.out.println("实现了这个类");
}
});
}
/**
* new Inter() {
*
* @Override
* public void show() {
* System.out.println("实现了这个类");
* }
* }
* 这一些在定义实现类的同时实例化了实现类:匿名内部类可以作为方法的实际参数进行传输
* //但是实现类必须要重写接口中所有抽象方法,如果抽象方法多,会变得可读性差,不好维护
*/
static void useInter(Inter i) {//Inter i =new InterImpl();//多态特性
//静态方法调用会成一个变量等待给它数据 Interface i=
i.show();//编译会检查Inter中有没有show()方法(多态)
}
}
interface Inter {
void show();//接口抽象方法
}
class InterImpl implements Inter {
@Override
public void show() {
System.out.println("implements...show...");
}
}
Lambda表达式简化匿名内部类
public class lambdaDemo1 {
/*
* Lambda表达式:JDK8开始的一种新的语法形式
*
* 作用:简化匿名内部类的代码写法
* 格式: () -> {}
* ():匿名内部类被重写方法的形参列表
* {}:被重写方法的方法体代码
* ->是语法形式,无实际含义
* */
public static void main(String[] args) {
useInter(()->{
System.out.println("Lambda表达式重写的抽象方法");
});
}
static void useInter(Inter i) {
i.show();
}
}
interface Inter {
void show();
}
反例:
public class LambdaDemo2 {
public static void main(String[] args) {
useInter(()-{});//编译错误
//Lambda表达式只允许操作函数式编程接口:有且仅有一个抽象方法的接口
}
static void useInter(Inter1 i) {
i.show1();
}
}
interface Inter1 {
void show1();
void show2();
}
注解@FunctionalInterface可以帮我们判断是不是函数式接口
Lambda省略规则
- 参数类型可以省略不写
- 如果只有一个参数,()也可以省略不写
- 如果Lambda表达式的方法体代码只有一行代码
可以省略大括号不写,同时必须省略分号
此时如果这行代码是return语句,还必须省略return
public class LambdaDemo2 {
public static void main(String[] args) {
useCal(new Calculator() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
System.out.println("----------------");
useCal((int a,int b)->{return a-b;});
System.out.println("省略写法");
useCal((a,b)-> a+b);
}
static void useCal(Calculator c) {
int calc = c.calc(10, 20);
System.out.println(calc);
}
}
interface Calculator {
int calc(int a, int b);
}
Lambda表达式和匿名内部类的区别
使用限制不同
- 匿名内部类:可以操作类,接口
- Lambda表达式:只能操作函数式接口
实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- Lambda表达式:编译之后没有单独的字节码文件