密封类是java15第一次预览,java17正式确定。Java15的密封类是一种确定了子类的类。这个改变是巨大的,以往的Java版本根本无法确定到底有哪些子类。而在java15中,如果定义了一个类为密封类就可以确定有哪些直接子类了。如下面的例子:

public sealed class PageQuery permits HouseQuery {

    private int page;
    private int size;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}

  我这个类就有个确定的房屋查询子类:

public final class HouseQuery extends PageQuery {
    private String building;

    public String getBuilding() {
        return building;
    }

    public void setBuilding(String building) {
        this.building = building;
    }
}

子类

  密封类的子类必须定义为final/sealed/non-sealed三种类型。这三种类型各有特点,final类是没有子类的,无需过多解释。non-sealed类是为了扩展,而sealed类是为了限定扩展。以下是一个non-sealed的例子:

@Data
public sealed class PageQuery permits AreaQuery {

    private int page;
    private int size;

}

  

@Data
public non-sealed class AreaQuery extends PageQuery {
    private String province;
    private String city;
    private String county;
}

密封接口

  我个人感觉密封接口的好处是可以马上知道有哪些实现类:

public sealed interface HouseService permits HouseServiceImpl {
}

  其实现类:

public non-sealed class HouseServiceImpl implements HouseService{
}

反射API

  新的反射API可以获取密封类的子类:

public class SealedDemo {
    public static void main(String[] args) {
        Class<PageQuery> clazz = PageQuery.class;
        System.out.println(clazz.isSealed());
        Class<?>[] subclasses = clazz.getPermittedSubclasses();
        for (Class<?> subclass: subclasses) {
            System.out.println(subclass);
        }
    }
}

  结果为:

true
class com.lintongai.java21demo.sealed.AreaQuery
03-17 23:25