JavaSE(新特性)

设计模式

模板方法

模板方法(Template Method):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。明确一部分功能,而另一部分功能不明确。需要延伸到子类中实现

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:50
 * @Description
 */
public abstract class Animal {
    public abstract void call();
}

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:51
 * @Description
 */
public class Cat extends Animal {
    @Override
    public void call() {
        System.out.println("cat call");
    }
}

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:51
 * @Description
 */
public class Dog extends Animal {

    @Override
    public void call() {
        System.out.println("dog call");
    }
}

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:53
 * @Description
 */
public class Test {
    public static void main(String[] args) {
        new Dog().call();
        new Cat().call();
    }
}

单例模式

目的:单例,让一个类只产生一个对象;
分类:
① 饿汉式
② 懒汉式

饿汉式

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:57
 * @Description
 */
public class Person {
    /*对象私有化*/
    private Person() {
    }

    // 随着类的加载而加载
    private static Person person = new Person();

    // 将内部new 的对象给外界
    public static Person getPerson() {
        return person;
    }
}

懒汉式

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 16:01
 * @Description
 */
public class Util {

    private Util() {
    }

    private static Util util = null;

    public static Util getUtil() {
        if (util == null) {
            synchronized (Util.class) {
                if (util == null) {
                    util = new Util();
                }
            }
        }
        return util;
    }
}

package alive.design;

/**
 * @Author zyj
 * @Date 2024/10/01 15:53
 * @Description
 */
public class Test {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Util util = Util.getUtil();
            System.out.println("util = " + util);
        }
    }
}

Lombok

简化JavaBean开发

Lombok通过增加一些“处理程序”,可以让java变得简洁
Lombok能以注解形式简化JavaBean代码,提高开发效率。开发中经常需要写Javabean,都需要去增加对应的getter/setter,构造器、equals等方法,需要维护。
Lombok能通过注解的方式,在编译时自动为属性生成构造器,getter、setter、equals、hashCode、toString方法。

package alive.lombok;

import lombok.Data;

/**
 * @Author zyj
 * @Date 2024/10/01 16:15
 * @Description
 */
//@Getter
//@Setter
//@ToString
//@AllArgsConstructor
//@NoArgsConstructor
@Data
public class Person {
    private String name;
    private Integer age;

}

@Data不提供有参构造

JDK新特性

Lambda 表达式

格式:
() -> {}
():重写方法的参数位置
->:将参数传入方法体中
{}:重写方法的方法体

package alive.lambda;

/**
 * @Author zyj
 * @Date 2024/10/01 16:57
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行了");
            }
        }).start();
        // lambda表达式
        new Thread(() -> System.out.println("执行了"));
    }

}

使用

① 必须是函数式接口作方法参数传递
② 有且只有一个抽象方法的接口,用@FunctionalInterface去检测在这里插入图片描述

package alive.lambda;

/**
 * @Author zyj
 * @Date 2024/10/01 17:40
 * @Description
 */
@FunctionalInterface
public interface USB {
    public void open();
}

① 观察是否是函数式接口作方法参数传递
② 调用方法,以匿名内部类的形式传递实参
③ 改造

package alive.lambda;

/**
 * @Author zyj
 * @Date 2024/10/01 17:40
 * @Description
 */
@FunctionalInterface
public interface USB {
    public void open();
}

package alive.lambda;

/**
 * @Author zyj
 * @Date 2024/10/01 17:43
 * @Description
 */
public class T2 {
    public static void main(String[] args) {
        open(new USB() {
            @Override
            public void open() {
                System.out.println("open");
            }
        });
        open(() -> {
            System.out.println("open");
        });
    }

    public static void open(USB usb) {
        usb.open();
    }
}

省略规则
① 重写方法的参数类型可省略
② 重写方法的参数只有一个可省略()
③ 方法体中,代码只有一行可省略{}
④ 方法体中,代码只有一行且return,可省略{} ;

package alive.lambda;

import java.util.ArrayList;
import java.util.Collections;

/**
 * @Author zyj
 * @Date 2024/10/01 17:52
 * @Description
 */
public class T3 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("Tom", 20));
        list.add(new Person("Alex", 10));
        list.add(new Person("Jack", 21));
//        Collections.sort(list, new Comparator<Person>() {
//            @Override
//            public int compare(Person o1, Person o2) {
//                return o1.getAge() - o2.getAge();
//            }
//        });
        System.out.println("list = " + list);
        Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println("list = " + list);
    }
}

函数式接口

Supplier

Supplier接口
java.util.function.Supplier< T >接口,它意味着“供给”
方法:
T get() 我们需要什么,get方法就可以返回什么
需求:
使用Supplier接口作为方法的参数
用Lambda表达式求出int数组中的最大值
泛型:
<引用数据类型> 规定了需要操作的数据类型

package alive.inter;

import java.util.Arrays;
import java.util.function.Supplier;

/**
 * @Author zyj
 * @Date 2024/10/01 20:05
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        sum(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int[] arr = {1, 2, 3, 4, 5, 6};
                Arrays.sort(arr);
                return arr[arr.length - 1];
            }
        });
        sum(() -> {
            int[] arr = {6, 1, 2, 1, 4};
            Arrays.sort(arr);
            return arr[arr.length - 1];
        });
    }

    public static void sum(Supplier<Integer> supplier) {
        Integer max = supplier.get();
        System.out.println("max = " + max);
    }
}

Consumer

java.util.function.consumer< T > 消费型接口
方法:
void accept(T t),意味着消费一个指定的泛型数据

package alive.inter;

import java.util.function.Consumer;

/**
 * @Author zyj
 * @Date 2024/10/01 20:15
 * @Description
 */
public class T2 {
    public static void main(String[] args) {
        print(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("s = " + s);
            }
        }, "alex");
        print(s -> {
            System.out.println("s = " + s);
        }, "Tom");
    }

    public static void print(Consumer<String> consumer, String s) {
        consumer.accept(s);
    }
}

Function

java.util.function.Function< T,R >:接口用来根据一个类型得到另一个类型的数据
方法:
R apply(T t):根据类型T参数获取类型R的结果

package alive.inter;

import java.util.function.Function;

/**
 * @Author zyj
 * @Date 2024/10/01 20:28
 * @Description
 */
public class T3 {
    public static void main(String[] args) {
        func(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer + "";
            }
        }, 100);
        func(i -> {
            return i + "";
        }, 10);
    }

    public static void func(Function<Integer, String> function, Integer number) {
        String str = function.apply(number);
        System.out.println("str = " + str + "a");
    }
}

Predicate

java.util.function.Predicate< T >接口,判断型接口
boolean test< T t > 用于判断的方法,返回值为boolean型

package alive.inter;

import java.util.function.Predicate;

/**
 * @Author zyj
 * @Date 2024/10/01 20:37
 * @Description
 */
public class T4 {
    public static void main(String[] args) {
        isBoolean(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 7;
            }
        }, "1234567");
        isBoolean(s -> s.length() == 7, "123457");
    }

    public static void isBoolean(Predicate<String> predicate, String s) {
        boolean test = predicate.test(s);
        System.out.println("test = " + test);
    }
}

Stream流

Stream流中的“流”不是特指“IO流”,它是一种“流式编程”(编程方式),可以看做是“流水线”

package alive.inter;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/01 21:23
 * @Description
 */
public class T5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张AA");
        list.add("张B");
        list.add("张CC");
        list.add("李D");
        list.add("王EE");
        list.add("张FF");
        Stream<String> stream = list.stream();
        stream.filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
    }
}

Stream的获取

① 针对集合,Collection中的方法:
Stream< E > stream()
② 针对数组,Stream接口的静态方法:
static < T > Stream < T > of(T ...value)

package alive.inter;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/01 21:39
 * @Description
 */
public class T6 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        Stream<String> stream1 = list.stream();
        System.out.println("stream1 = " + stream1);
        Stream<String> stream2 = Stream.of("张三", "李四", "王五");
        System.out.println("stream2 = " + stream2);
        //stream1 = java.util.stream.ReferencePipeline$Head@214c265e
        //stream2 = java.util.stream.ReferencePipeline$Head@448139f0
    }
}

Stream的方法

forEach

Stream 中的forEach方法:void forEach(Consumer< ? super T> action)
forEach:逐一遍历,是一个终结方法,使用完之后Stream流就不能再使用

package alive.inter;

import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:16
 * @Description
 */
public class T7 {
    public static void main(String[] args) {
        print();
    }

    public static void print() {
        Stream<String> stream = Stream.of("A", "B", "C", "D");
        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("s = " + s);
            }
        });
        stream.forEach(s -> System.out.println(s));

    }
}

在这里插入图片描述

第二个forEach就会报错

Count()

long count()
统计元素个数
count也是个终结方法

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:28
 * @Description
 */
public class T8 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("A", "B", "C", "D");
        long count = stream.count();
        System.out.println("count = " + count);
    }
}

filter()

Stream< T > filter(Predicate< ? super T> predicate)方法,返回一个新的Stream流对象
根据某个条件进行元素过滤

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:33
 * @Description
 */
public class T9 {
    public static void main(String[] args) {
        Stream<Person> stream = Stream.of(new Person(10, "Tom"), new Person(20, "Jack"), new Person(30, "Alex"));
        stream.filter(p -> p.getAge() <= 10).forEach(p -> {
            System.out.println("p = " + p);
        });
    }
}

limit()

Stream < T > limit(long maxSize):获取Stream流对象中的前n个元素,返回一个新的Stream流对象

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:39
 * @Description
 */
public class T10 {
    public static void main(String[] args) {
        Stream<Person> stream = Stream.of(new Person(10, "Tom"), new Person(20, "Jack"), new Person(30, "Alex"));
        stream.limit(1).forEach(p -> {
            System.out.println("p = " + p);
        });
    }
}

skip

Stream < T > skip(long n):跳过Stream流对象中的前n个元素,返回一个新的Stream流对象

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:44
 * @Description
 */
public class T11 {
    public static void main(String[] args) {
        Stream<Person> stream = Stream.of(new Person(10, "Tom"), new Person(20, "Jack"), new Person(30, "Alex"));
        stream.skip(2).forEach(p -> {
            System.out.println("p = " + p);
        });
        //p = Person(age=30, name=Alex)
    }
}

concat()

static < T > Stream< T >concat(Stream < ? extends T> a,Stream < ? extends T> b):将两个Stream流合并成一个

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:48
 * @Description
 */
public class T12 {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("A", "B", "C");
        Stream<String> stream2 = Stream.of("D", "E", "F");
        Stream.concat(stream2, stream1).forEach(s -> {
            System.out.println("s = " + s);
        });
        //s = D
        //s = E
        //s = F
        //s = A
        //s = B
        //s = C
    }
}

collect()

从Stream流对象转成集合对象

package alive.inter;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:52
 * @Description
 */
public class T13 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("A", "B", "C");
        List<String> list = stream.collect(Collectors.toList());
    }
}

dinstinct()

Stream< T > distinct()
元素去重复,依赖hashCode和equals方法

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:55
 * @Description
 */
public class T14 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("A", "B", "C", "C");
        stream.distinct().forEach(s -> {
            System.out.println("s = " + s);
        });
        //s = A
        //s = B
        //s = C
    }
}

package alive.inter;

import lombok.Data;

/**
 * @Author zyj
 * @Date 2024/10/02 10:33
 * @Description
 */
@Data
public class Person {
    public Person() {
    }

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    private Integer age;
    private String name;
}

package alive.inter;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 10:55
 * @Description
 */
public class T14 {
    public static void main(String[] args) {
        Stream<Person> stream = Stream.of(new Person(10, "Tom"), new Person(10, "Tom"), new Person(30, "Alex"));
        stream.distinct().forEach(person -> {
            System.out.println("person = " + person);
        });
        //person = Person(age=10, name=Tom)
        //person = Person(age=30, name=Alex)
    }
}

map

``Stream< R > map(Function<T , R> mapper):转换流中的数据类型

package alive.inter;

import java.util.function.Function;
import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 11:03
 * @Description
 */
public class T15 {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7);
        stream.map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer + "";
            }
        }).forEach(i -> {
            System.out.println("i = " + i);
        });
    }
}

方法引用

引用方法
使用:
① 被引用的方法要写在重写方法中
② 被引用的方法从参数上,返回值上要和所在重写方法一致,而且引用的方法最好是操作重写方法的参数值的
③ 去除重写方法的参数,去除 ->,去除引用方法的参数,将被引用的方法.改成::

package alive.method;

import java.util.stream.Stream;

/**
 * @Author zyj
 * @Date 2024/10/02 12:09
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("A", "B", "C");
//        stream.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
//        stream.forEach(s -> System.out.println(s));
        stream.forEach(System.out::println);
    }
}

对象名-引用成员方法

使用对象名引用成员方法
格式:
对象::成员方法名

函数式接口:supplier
java.util.function.Supplier< T >接口
抽象方法:
T get(),用来获取一个泛型参数指定类型的对象数据
Supplier接口使用什么泛型,就可以使用get获取一个什么类型的数据

package alive.method;

import java.util.function.Supplier;

/**
 * @Author zyj
 * @Date 2024/10/02 12:29
 * @Description
 */
public class T2 {
    public static void main(String[] args) {
        print(new Supplier<String>() {
            @Override
            public String get() {
                return " abc ".trim();
            }
        });
        print(() -> " abc ".trim());
        print(" abc "::trim);
    }

    public static void print(Supplier<String> supplier) {
        String str = supplier.get();
        System.out.println("str = " + str);
    }
}

类名-引用静态方法

格式
类名::静态成员方法

package alive.method;

import java.util.function.Supplier;

/**
 * @Author zyj
 * @Date 2024/10/02 12:40
 * @Description
 */
public class T3 {
    public static void main(String[] args) {
        print(new Supplier<Double>() {
            @Override
            public Double get() {
                return Math.random();
            }
        });
        print(() -> Math.random());
        print(Math::random);
    }

    public static void print(Supplier<Double> supplier) {
        Double aDouble = supplier.get();
        System.out.println("aDouble = " + aDouble);
    }
}

类-构造引用

类 - 构造方法引用
格式:
构造方法名::new

函数式接口:Function
java.util.function.Function< T,R>接口
抽象方法
R apply(T t),根据类型T的参数获取类型R的结果。用于数据类型转换

package alive.method;

import java.util.function.Function;

/**
 * @Author zyj
 * @Date 2024/10/02 12:43
 * @Description
 */
public class T4 {
    public static void main(String[] args) {
        print(new Function<String, Person>() {
            @Override
            public Person apply(String s) {
                return new Person(s);
            }
        }, "Tom");
        print(s -> new Person(s), "Jack");
        print(Person::new, "Alex");

    }

    public static void print(Function<String, Person> function, String name) {
        Person p = function.apply(name);
        System.out.println("p = " + p);
    }
}

数组-数组引用

格式:
数组的数据类型[]::new
int [] :: new 创建一个int型的数组
double[] ::new 创建一个double型的数组

package alive.method;

import java.util.function.Function;

/**
 * @Author zyj
 * @Date 2024/10/02 13:23
 * @Description
 */
public class T5 {
    public static void main(String[] args) {
        print(new Function<Integer, int[]>() {
            @Override
            public int[] apply(Integer integer) {
                return new int[integer];
            }
        }, 10);
        print(length -> new int[length], 2);
        print(int[]::new, 4);
    }

    public static void print(Function<Integer, int[]> function, Integer length) {
        int[] arr = function.apply(length);
        System.out.println("arr = " + arr.length);
    }
}

JDK8之后的新特性

接口的私有方法

Java8版本接口直接了两类成员:

  • 公共的默认方法
  • 公共的静态方法

Java9版本接口又新增了一类成员:

  • 私有方法:因为有了默认方法和静态方法这样具有具体实现的方法,那么就可能出现多个方法由共同的代码可以抽取,而这些共同的代码抽取出来的方法又只希望在接口内部使用,所以就增加了私有方法。
package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 13:30
 * @Description
 */
public interface USB {
    private void open() {
        System.out.println("私有非静态方法");
    }

    private static void close() {
        System.out.println("私有静态方法");
    }

    public default void def() {
        open();
        close();
    }
}

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 13:33
 * @Description
 */
public class USBImpl implements USB {
}

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 13:33
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        USBImpl usb = new USBImpl();
        usb.def();
    }
}

砖石操作符与匿名内部类结合

自Java9 之后我们将能够与匿名实现类共同使用砖石操作符,即匿名实现类也支持类型自动推断

package alive.newJDK;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * @Author zyj
 * @Date 2024/10/02 13:49
 * @Description
 */
public class T2 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person(10, "Tom"));
        list.add(new Person(9, "Jack"));
        list.add(new Person(8, "Alex"));
        Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println("list = " + list);
    }
}

Java 8 的语言等级编译会报错,cannot be used with anonymous classesJava 9 以上版本才能编译和运行

try…catch升级

try(IO流对象1声明和初始化;IO流对象2声明和初始化){
可能出现异常的代码
}catch(异常类型 对象名){
异常处理方案
}

JDK1.9对trywitch-resources的语法升级了

  • 该资源必须实现java.io.closeable接口
  • 在try子句中声明并初始化资源对象,也可以直接使用已初始化的资源对象
  • 该资源对象必须是final的

IO流对象1 声明和初始化
IO流对象2 声明和初始化
try(IO流对象1,IO流对象2){
可能出现异常的代码
} catch(异常类型 对象名){
异常处理方案
}

局部变量类型自动推断

JDK 10 之前,我们定义局部变量都必须要明确数据的数据类型,但是到了JDK 10,出现了局部变量类型推断,顾名思义,就是定义局部变量时,不用先确定具体的数据类型,可以根据具体数据推断出所属的数据类型。
var 变量名 = 值

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 14:05
 * @Description
 */
public class T3 {
    public static void main(String[] args) {
        var i = 10;
        System.out.println(i);
        var arr = new int[]{1, 2, 3, 4, 5};
        for (int el : arr) {
            System.out.println("el = " + el);
        }
    }
}

switch

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 14:50
 * @Description
 */
public class T4 {
    public static void main(String[] args) {
        int sco = 3;
        switch (sco) {
            case 1, 2:
                System.out.println("差");
                break;
            case 3, 4:
                System.out.println("中");
                break;
            case 5, 6:
                System.out.println("优");
                break;
            default:
                System.out.println("未知");
                break;
        }
        // JDK 12
        switch (sco) {
            case 1, 2 -> System.out.println("差");
            case 3, 4 -> System.out.println("中");
            case 5, 6 -> System.out.println("优");
            default -> System.out.println("未知");
        }
        // JDK 13
        var res = switch (sco) {
            case 1, 2 -> {
                yield "差";
            }
            case 3, 4 -> {
                yield "中";
            }
            case 5, 6 -> {
                yield "优";
            }
            default -> {
                yield "未知";
            }
        };
        System.out.println("res = " + res);
    }
}

文本块

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:12
 * @Description
 */
public class T5 {
    public static void main(String[] args) {
        var str = """
                <html>
                    <body>
                        <p> hello world </p>
                    </body>
                </html>
                """;
        System.out.println("str = " + str);
    }
}

instanceof 模式匹配

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:46
 * @Description
 */
public class T6 {
    public static void main(String[] args) {
        action(new Dog());
        action(new Cat());
    }

    public static void action(Animal animal) {
        if (animal instanceof Dog dog) {
            dog.pro();
            dog.call();
        } else if (animal instanceof Cat cat) {
            cat.call();
        }
    }
}

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:44
 * @Description
 */
public abstract class Animal {
    public abstract void call();
}

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:45
 * @Description
 */
public class Cat extends Animal {

    @Override
    public void call() {
        System.out.println("cat call");
    }
}

package alive.newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:45
 * @Description
 */
public class Dog extends Animal {
    @Override
    public void call() {
        System.out.println("dog call");
    }

    public void pro() {
        System.out.println("保护主人");
    }
}

Record类

package alive.a_newJDK;

public record Person(String name) {
    /**
     * ① 不能声明实例变量
     * ② 可以声明静态变量
     * ③ 不能声明空参构造
     * ④ 可以声明静态方法
     * ⑤ 可以声明非静态方法
     */
//     int i;
//    public Person(){}
    public static void print() {
    }

    public void call() {
    }
}

package alive.a_newJDK;

/**
 * @Author zyj
 * @Date 2024/10/02 15:55
 * @Description
 */
public class T1 {
    public static void main(String[] args) {
        Person tom = new Person("Tom");
        System.out.println("tom = " + tom);
    }
}

密封类

很多语言都有密封类的概念,在Java语言中,最早就有密封类的思想,就是final修饰的类,该类不允许被继承。而JDK15开始,针对密封类进行了升级
Java15 通过密封的类和接口来增强Java编程而言,这是新引入的预览功能并在Java 16中进行了二次预览,并在Java 17最终确定下来。这个预览功能用于限制超类的使用,密封的类和接口限制其他可能继承或实现他们的其他类或接口

【修饰符】 sealed class 密封类 【extend 父类】【implements 父接口】permits 子类{}
【修饰符】sealed interface 接口 【extends 父接口们】 permits 实现类{}

  • 密封类用sealed修饰符来修饰
  • 使用permits关键字来指定可以继承或实现该类的类型有哪些
  • 一个类继承密封类或实现密封接口,该类必须是sealed 、non-sealed、final修饰的
  • sealed修饰的类或接口必须有子类或实现类
public sealed class Animal permits Dog,Cat{

}
public non-sealed class Dog extends Animal{

}
public non-sealed class Cat extends Animal{

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值