1-接口新特性
1.1-jdk8的新特性
接口中可以定义有方法体的方法。(默认、静态)
目的:对接口功能做新增时不改变实现类的代码
默认方法
格式:
public default 返回值类型 方法名(参数列表){}
价值:解决接口的升级问题(打补丁)
注意:如果一个实现类进行多实现,而实现的接口中有相同声明的默认方法,则要么进行方法重写,要么进行A.super.方法名。以此来避免逻辑冲突问题。
静态方法
格式:
static 返回值类型 方法名(参数列表){}
调用方式: 接口名.方法名
1.2-jdk9的新特性
接口中允许定义私有方法
2-代码块
2.1-介绍
在Java类下,使用{}括起来的代码称为代码块
2.2-局部代码块
方法中的一对{}
目的:限定变量的生命周期,提早释放内存
2.3-构造代码块
类中方法外的一对{}
在new对象的时候被调用执行,无论用空参还是带参,都先于空参/带参方法执行
使用场景:发现多个构造方法中存在相同代码,就可考虑将其抽取到构造代码块中。
2.4-静态代码块
类中方法外,被static修饰
格式: static{}
静态代码块随着类的加载而执行,且只会执行一次(因为类只加载一次)
使用场景:在项目启动的时候,加载配置文件
2.5-同步代码块
多线程中学习,暂时搁置
2.6-代码块练习
package com.lyl.codeblock;
public class CodeTest {
static {
System.out.println("CodeTest2静态代码块");
}
{
System.out.println("CodeTest2构造代码块");
}
public static void main(String[] args) {
Demo d = new Demo(10);
CodeTest c = new CodeTest();
}
}
class Demo {
static {
System.out.println("Demo类静态代码块...");
}
{
System.out.println("Demo类构造代码块");
}
public Demo() {
System.out.println("Demo类无参构造方法");
}
public Demo(int num) {
System.out.println("Demo类带参构造方法");
}
}
务必清楚执行流程 !
3-内部类
3.1-介绍
内部类就是 定义在 一个类 里面的 类
class test{
class intest{
sout("test...intest")
}
}
3.2-内部类创建对象的格式
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
3.3-内部类成员访问
内部类中,访问外部类成员:直接访问,包括私有
外部类中,访问内部类成员:需要创建对象访问
3.4-内部类的分类
成员内部类
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
内部类中,访问外部类成员:直接访问,包括私有
外部类中,访问内部类成员:需要创建对象访问
静态内部类
-
static{}
局部内部类
(鸡肋语法 ,了解即可)
-
局部内部类放在方法、代码块、构造器等执行体中。
匿名内部类
本质上是一个特殊的局部内部类(编写位置在方法中)
前提:
-
要有类或者是接口
为了解决的情况:
当我们调用一个方法的时候,发现方法的形参 是一个接口,我们需要 :
编写实现类实现接口
重写方法
创建实现类对象传入实参
用 匿名内部类 实现 :
package com.lyl.inter;
public class Test {
public static void main(String[] args) {
useInter(new Inter() {
@Override
public void show() {
System.out.println("匿名内部类重写后的show方法...");
}
});
}
public static void useInter(Inter i){
i.show();
}
}
interface Inter{
void show();
}
使用总结:匿名内部类可以作为方法的实际参数进行传输
当方法参数为接口时,且需要重写的方法少时,就可以考虑使用匿名内部类
当方法参数为接口时,且需要重写的方法多时,就可以考虑写一个实现类
4-Lambda表达式
4.1概述
Lambda表达式是JDK8开始后的一种新语法形式。
作用:简化匿名内部类的代码写法。
Lambda表达式的简化格式
格式:
() -> {}
(匿名内部类被重写方法的形参列表) -> {
被重写方法的方法体代码。
}
注:->是语法形式,无实际含义
注意:Lambda表达式只能简化函数式接口的匿名内部类的写法形式
函数式接口:有且只有一个抽象方法的接口(默认方法也可放进去)
-
练习
package com.lyl.lambda;
public class LambdaTest1 {
public static void main(String[] args) {
useShowHandler(new ShowHandler() {
@Override
public void show() {
System.out.println("匿名内部类重写show方法");
}
});
useShowHandler(() -> {
System.out.println("Lambda表达式重写show方法");
});
}
public static void useShowHandler(ShowHandler showHandler) {
showHandler.show();
}
}
interface ShowHandler {
void show();
}
package com.lyl.lambda;
public class LambdaTest2 {
public static void main(String[] args) {
useStringHandler(new StringHandler() {
@Override
public void printMessage(String msg) {
System.out.println("匿名内部类重写printMessage方法" + msg);
}
});
useStringHandler((String msg) -> {
System.out.println("Lambda表达式重写printMessage方法" + msg);
});
}
public static void useStringHandler(StringHandler stringHandler) {
stringHandler.printMessage("printMessage");
}
}
interface StringHandler {
void printMessage(String msg);
}
package com.lyl.lambda;
import java.util.Random;
public class LambdaTest3 {
public static void main(String[] args) {
useRandomNumHandler(new RandomNumHandler() {
@Override
public int getNumber() {
return new Random().nextInt(100) + 1;
}
});
//Lambda表达式
useRandomNumHandler(() -> {
return new Random().nextInt(100) + 1;
});
}
public static void useRandomNumHandler(RandomNumHandler randomNumHandler) {
int result = randomNumHandler.getNumber();
System.out.println(result);
}
}
interface RandomNumHandler {
int getNumber();
}
package com.lyl.lambda;
public class LambdaTest4 {
public static void main(String[] args) {
useCalculator(new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
});
//Lambda表达式简化格式
useCalculator(((a, b) -> a - b));
}
public static void useCalculator(Calculator calculator) {
int result = calculator.calc(10, 20);
System.out.println(result);
}
}
interface Calculator {
int calc(int a, int b);
}
4.2省略写法
参数的类型可以省略不写
如果只有一个参数,参数类型可以省略,同时()也可以省略
如果Lambda表达式的方法体只有一行代码,可以省略大括号不写,同时要省略分号 此时,如果这行代码是returni语句,必须省略return不写,同时也必须省略";"不写
useShowHandler(() -> System.out.println("匿名内部类重写show方法"));
useStringHandler(msg -> System.out.println("匿名内部类重写printMessage方法" + msg));
useRandomNumHandler(() -> new Random().nextInt(100) + 1);
useCalculator(((a, b) -> a - b));
5-Lambda表达式和匿名内部类的区别
Lambda表达式不是匿名内部类的语法糖
使用限制不同
匿名内部类:可以操作类,接口
Lambda表达式:只能操作函数式接口
实现原理不同
匿名内部类:编译之后,产生一个单独的.class字节码文件
Lambda:表达式:编译之后,没有一个单独的.class字节码文件
6-模板设计模式
模板设计模式:把抽象类整体就可以看做成一个模板,模板中不能决定的东西定义成抽象方法 让使用模板的类(继承抽象类的类)去重写抽象方法实现需求