JEP 360: Sealed Types (Preview)


While half the world has been locked up in self-isolation, there are rumors that Java 15 might join the flash mob. If people cannot be propagated in Belgium , then why should classes be inherited uncontrollably, is that true?


JEP β€” Java, Β«sealed typesΒ» ( ). β€” , .



  • , ;
  • , ;
  • -, .


  • , friend;
  • final.


Java . . , . , β€” , , . , .


, , Shape , Shape, β€” . , Shape, Shape. Shape, , . , Java : Shape -, . : , - . , "" , .


Java- , API. : final, , ( ) package-private, . , package-private JDK ( OpenJDK):


package java.lang;

abstract class AbstractStringBuilder {...}
public final class StringBuffer  extends AbstractStringBuilder {...}
public final class StringBuilder extends AbstractStringBuilder {...}

package-private , β€” , AbstractStringBuilder, - . , , β€” β€” . , ! ( , Shape , , Shape).


, ( ), ( , ). , -. ( ), Java ( ). , , , final .



, .


sealed . extends- implements-, permits , . , Shape :


package com.example.geometry;

public sealed class Shape
    permits Circle, Rectangle, Square {...}

, permits : ( ), ( ). , Shape, , :


package com.example.geometry;

public sealed class Shape 
    permits com.example.polar.Circle,
            com.example.quad.Rectangle,
            com.example.quad.simple.Square {...}

( ), , . , permits, Java ( , auxilliary nested ). , Shape.java Shape :


package com.example.geometry;

sealed class Shape {...}
... class Circle    extends Shape {...}
... class Rectangle extends Shape {...}
... class Square    extends Shape {...}

instanceof catch:


Shape rotate(Shape shape, double angle) {
    if (shape instanceof Circle) return shape;
    else if (shape instanceof Rectangle) return shape.rotate(angle);
    else if (shape instanceof Square) return shape.rotate(angle);
}

, Java , instanceof Shape. , instanceof Rectangle, .


-. , if-else, , JEP 375. Java , (exhaustive) . , , Shape, default. , , :


Shape rotate(Shape shape, double angle) {
    return switch (shape) {
        case Circle c    -> c;  // no action needed
        case Rectangle r -> r.rotate(angle);
        case Square s    -> s.rotate(angle);
    }
}

Sealed class (, permits):


  1. . , . , , . , , , default ( ). Java , , default;
  2. ;
  3. , , , .

  • final ;
  • sealed, , , ;
  • non-sealed, β€” . ( ).

:


package com.example.geometry;

public sealed class Shape
    permits Circle, Rectangle, Square {...}

public final class Circle extends Shape {...}

public sealed class Rectangle extends Shape 
    permits TransparentRectangle, FilledRectangle {...}
public final class TransparentRectangle extends Rectangle {...}
public final class FilledRectangle extends Rectangle {...}

public non-sealed class Square extends Shape {...}

final, sealed non-sealed. sealed (, ) final (, ). sealed ( ) non-sealed ( ). non-sealed ( ) final ( ).


final , . , final sealed + permits . , permits Java .



, β€” sealed. extends, permits.


package com.example.expression;

public sealed interface Expr
    permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {...}

public final class ConstantExpr implements Expr {...}
public final class PlusExpr     implements Expr {...}
public final class TimesExpr    implements Expr {...}
public final class NegExpr      implements Expr {...}

(records)


(JEP 359), Java 14. final, , :


package com.example.expression;

public sealed interface Expr
    permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {...}

public record ConstantExpr(int i)       implements Expr {...}
public record PlusExpr(Expr a, Expr b)  implements Expr {...}
public record TimesExpr(Expr a, Expr b) implements Expr {...}
public record NegExpr(Expr e)           implements Expr {...}

. -, β€” -.


JDK


java.lang.constant package, JVM:


package java.lang.constant;

public sealed interface ConstantDesc
    permits String, Integer, Float, Long, Double,
            ClassDesc, MethodTypeDesc, DynamicConstantDesc {...}

// ClassDesc      JDK
public sealed interface ClassDesc extends ConstantDesc
    permits PrimitiveClassDescImpl, ReferenceClassDescImpl {...}
final class PrimitiveClassDescImpl implements ClassDesc {...}
final class ReferenceClassDescImpl implements ClassDesc {...} 

// MethodTypeDesc      JDK
public sealed interface MethodTypeDesc extends ConstantDesc
    permits MethodTypeDescImpl {...}
final class MethodTypeDescImpl implements MethodTypeDesc {...}

// DynamicConstantDesc     
public non-sealed abstract class DynamicConstantDesc implements ConstantDesc {...}

Java


NormalClassDeclaration:
  {ClassModifier} class TypeIdentifier [TypeParameters]
  [Superclass] [Superinterfaces] [PermittedSubclasses] ClassBody

ClassModifier:
  (one of)
  Annotation public protected private
  abstract static sealed final non-sealed strictfp

PermittedSubclasses:
  permits ClassTypeList

ClassTypeList:
  ClassType {, ClassType}


, sealed β€” , ClassFile ACC_SEALED. , PermittedSubtypes, sealed :


PermittedSubtypes_attribute {
    u2 attribute_name_index;
    u4 attribute_length;
    u2 permitted_subtypes_count;
    u2 classes[permitted_subtypes_count];
}

permits, PermittedSubtypes , , , .


.



java.lang.Class :


  • java.lang.constant.ClassDesc[] getPermittedSubtypes()
  • boolean isSealed()

getPermittedSubtypes() , java.lang.constant.ClassDesc, , , β€” .


isSealed true, ( isEnum).



(ADT), , data Haskell. , ADT , Java-. , - enum, , . , (, ).


permits , Shape , -- , , -- ( unnamed module). , . , Shape -- ( ), Shape -- . Shape -- , Shape -- .




JEP- JUG Ru Group JPoint. JPoint 8 ( β€” ). !


All Articles