一、内部类
内部类概述
类中类,在类中在定义一个类
格式:
//外部类 public class Outer{ //内部类 public class Inner{
} }
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有的
外部类访问成员变量必须要创建对象才能访问
内部类的分类
成员内部类(不常用)
含义:成员变量、成员方法平级的类
特点:使其私有化,在类中使用不允许被调用
局部内部类(不常用)
含义:方法中定义的类
特点: 1.只能在方法方法中创建并使用
2.能访问外部类成员,也可访问方法内局部变量
匿名内部类(相对来说用的比较多)
匿名对象:没有名字的对象只使用一次
前提条件:存在一个类或者接口,也可是抽象类
格式:new 类名或者接口名() {重写方法};
本质:继承了该类的子类匿名对象或者是实现了该接口的的实现类匿名对象
二、什么是Lambda表达式?及其作用
lambda表达式是一种书写的风格
它的作用主要就是简洁流畅的写法来代替匿名内部类的写法
Lambda的使用的前提条件:
该接口为函数式接口:接口中只有一个抽象方法的接口就称之为函数式接口,也可以加上【@Functionallnterface】注解来进行辨识接口是否为函数式接口。
Lambda的使用格式
() -> {}
小括号里面为参数,大括号里面为方法体
Lambda的省略格式
1.参数类型可以省略 (当多个参数时,参数类型相同也省略)
2.如果参数只有一个,小括号也可以省略
3.代码块中只有一条语句的话,也可以省略如果有return,return也要省略。
方法的引用
1.构造方法引用:
当构造器的参数列表与函数式接口的参数列表一致时,可以使用;
使用方式: 类名::new
2.普通方法引用:
实例方法的参数列表,返回类型与函数式接口一致时可以使用;
使用方式: 对象::方法名 或者 类名::方法名
使用案例:
Student类:
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
Get方法
public interface Get {
String get();
}
闭包
当lambda表达式访问外部变量的时候,会自动加上final 要想要对外部变量进行一个修改把数字先变为数组进行操作
Sing sing1=(songs) -> {
a[0]++;
System.out.println(a[0]);
System.out.println(songs);
};
a[0]++;
sing1.sing(100);
三、匿名内部类和Lambda的区别
所需类型不同:
匿名内部类:在实现前可以使用接口、抽象类、普通类
Lambda表达式的实现前提必须式接口
使用限制不同:
如果接口中只有一个抽象方法既可以用Lambda也可以用匿名内部类
当接口中有多个抽象方法的话只能使用匿名内部类
实现原理不同
匿名内部类编译之后会产出一个单独的字节码.class文件
lambda不会独立产出字节码文件,对应的字节码文件在运行时产生