рдЬрд╛рд╡рд╛ рднрд╛рд╖рд╛ рдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрдиреЗ рдХреА рд╢реБрд░реБрдЖрдд рдХреА рд╣реИред рдЬрд╛рд╡рд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдЫрд╣ рдорд╣реАрдиреЗ рдХреА рд░рд┐рд▓реАрдЬ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЦреБрд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИредрдЬрд╛рд╡рд╛ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рд╣реИред рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЫреЛрдбрд╝рддреЗ рд╕рдордп рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдврдВрдЧ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддрд╛ рд╣реИредрдЬрд╛рд╡рд╛ рдореЗрдВ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рдкреНрд░рдореБрдЦ рдмреНрд▓реЙрдХ рд░рд┐рдХреЙрд░реНрдб рдФрд░ рд╕реАрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВредрд░рд┐рдХреЙрд░реНрдб рдЙрди рд╡рд░реНрдЧреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдирд┐рд░рдВрддрд░, рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЗ рд╕рд░рд▓ рд╡рд╛рд╣рдХ рд╣реИрдВредрдЬрд╛рд╡рд╛ 14 рдореЗрдВ рдПрдХ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛редrecord Person(String name, int age) { }
рд╕реАрд▓ рдкреНрд░рдХрд╛рд░ рд╡реЗ рд╡рд░реНрдЧ рдпрд╛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рд╡рд░реНрдЧреЛрдВ рдпрд╛ рдЙрди рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдЬреЛ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдпрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рд╛рдпрд┐рдХрддрд╛ рдХреА рдПрдХ рдЙрдЪреНрдЪ рдбрд┐рдЧреНрд░реА рдХреЗ рд╕рд╛рде рд╡реЗ рдЬрд╛рд╡рд╛ 15. рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддреЗ рд╣реИрдВредрд╡реЗ рд╕реНрдЯреЗрд░реЙрдпрдб рдкрд░ Enum рдкреНрд░рдХрд╛рд░ рд╣реИрдВредsealed interface Color permits BiColor, TriColor { }
record BiColor(int r, int g, int b) implements Color {}
record TriColor(int r, int g, int b) implements Color {}
рдПрдХ рд╕реАрд▓ рдХрд┐рдП рдЧрдП рд╕рдВрд╢реЛрдзрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рд╕реАрд▓ рдХрд┐рдП рдЧрдП рд╡рд░реНрдЧ рдпрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрдк-рд╕реВрдЪрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреАрдХреЛ рдкрд░рдорд┐рдЯ рдХреАрд╡рд░реНрдб рдХреЗ рдмрд╛рдж рд╕реАрд▓ рдХрд┐рдП рдЧрдП рд╡рд░реНрдЧ рдпрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдШреЛрд╖рдгрд╛ рд╕рдордп рдкрд░ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдпрджрд┐ рдЙрдкрдкреНрд░рдХрд╛рд░ рдПрдХ рд╣реА рдкреИрдХреЗрдЬ рдпрд╛ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИрдВ, рддреЛ рд╕рдВрдХрд▓рдХ рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕реАрд▓рдмрдВрджрд╡рд░реНрдЧ рдпрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рдШреЛрд╖рдгрд╛ рдореЗрдВ рдкрд░рдорд┐рдЯ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрдпрджрд┐ рдЙрдк-рдкреНрд░рдХрд╛рд░ рдЕрдореВрд░реНрдд рд╣реИ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рддрдХ рдХрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдЧреИрд░-рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредрдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╛рд╡рд╛ рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреАрд╡рд░реНрдб рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рд╛рдЗрдлрд╝рдиреЗрдЯреЗрдб рдХреАрд╡рд░реНрдб рдХрд╣рддреЗ рд╣реИрдВ редрдРрд╕реЗ рдХреАрд╡рд░реНрдб рдореЗрдВ рдбреИрд╢ рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рджреЛ рд╢рдмреНрдж рд╣реЛрдВрдЧреЗредрдЬрдм рддрдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЧреИрд░-рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм рддрдХ рдХрдВрдХреНрд░реАрдЯ рдЙрдкрдкреНрд░рдХрд╛рд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдВрддрд┐рдо рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдЕрдЧрд░ рдЖрдк рдЗрд╕реЗ рдЕрдВрддрд┐рдо рдирд╣реАрдВ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЧреИрд░-рдлрд╛рдЗрдирд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛редрд╕реАрд▓рдмрдВрдж рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирдИ PermittedSubtypes рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд╡рд░реНрдЧ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЙрдк-рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИредPermittedSubtypes_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 permitted_subtypes_count;
u2 classes[permitted_subtypes_count];
}
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореБрд╣рд░рдмрдВрдж рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, java.lang.Class рдореЗрдВ рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдБ рдЬреЛрдбрд╝реА рдЬрд╛рддреА рд╣реИрдВредjava.lang.constant.ClassDesc<?>[] getPermittedSubtypes()
boolean isSealed()
рдкрд╣рд▓реА рд╡рд┐рдзрд┐ java.lang.constant.ClassDesc рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╕рдмрдЯрд╛рдЗрдкреНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рд╡рд░реНрдЧ рдПрдХ рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИред рдпрджрд┐ рд╡рд░реНрдЧ рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдПрдХ рдЦрд╛рд▓реА рд╕рд░рдгреА рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рджреА рдЧрдИ рдХрдХреНрд╖рд╛ рдпрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдПрдХ рд╕реАрд▓ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИ, рддреЛ рджреВрд╕рд░реА рд╡рд┐рдзрд┐ рд╕рд╣реА рд╣реИредрдпрд╣ рд╕рдм рд╕рдВрдХрд▓рдХ рдХреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╕рднреА рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдЬрдм рдПрдХ рд╕реНрд╡рд┐рдЪ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ рд╣реЛрддреА рд╣реИредvar result = switch (color) {
case BiColor bc -> 0x1;
case TriColor tc -> 0x2;
}
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╢рд╛рдЦрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рднреА рд╡реИрдз рдЙрдк-рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИредрдФрд░ рдЕрдЧрд░ рдПрдХ рдирдпрд╛ рдЙрдкрдкреНрд░рдХрд╛рд░ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдВрдХрд▓рдХ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рд╕рднреА рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдореЗрдВ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдВрдХрд▓рди рд╕рдордп рдореЗрдВ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреЗрдЧрд╛редрд╕реАрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдирдпрд╛ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрдЯрд▓рд┐рди рднрд╛рд╖рд╛ рдореЗрдВ, рд╕реАрд▓рдмрдВрдж рдХрдХреНрд╖рд╛рдПрдВ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХреЛрдИ рд╕реАрд▓рдмрдВрдж рдЗрдВрдЯрд░рдлреЗрд╕ рдирд╣реАрдВ рд╣реИрдВредsealed class Color
data class BiColor(val r: Int, val g: Int, val b: Int) : Color
data class TriColor(val r: Int, val g: Int, val b: Int) : Color
рдХреЛрдЯрд▓рд┐рди рд╕реАрд▓рдмрдВрдж рдХрдХреНрд╖рд╛рдПрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рд╕рд╛рд░ рд╣реИрдВ рдФрд░ рдПрдХ рдирд┐рдЬреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╣реИрдВред рддрджрдиреБрд╕рд╛рд░, рдЙрдк-рд╡рд░реНрдЧ рдХреЛ рд╡рд░реНрдЧ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрд╛рд╡рд╛ рдореЗрдВ, рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредpublic abstract class Color {
private Color() {}
public static class BiColor(int r, int g, int b) extends Color {}
public static class TriColor(int r, int g, int b) extends Color {}
}
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдХрд┐ рд╕рднреА рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрдпрд╣ рд╕рдм рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рд╕реАрд▓ рдХреА рдЧрдИ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЕрднреА рддрдХ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдЖрдП рд╣реИрдВред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдХреБрдЫ рднреА рдирд╣реАрдВ рдПрдХ рд╕рд░рд▓ рдЖрдЧрдВрддреБрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ, рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдЬрдм рдХреЛрдЯрд▓рд┐рди рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛рдо рдХрд░рддреА рд╣реИред matches(color).as(
Color.BiColor.class, bc -> System.out.println("bi color: " + bc),
Color.TriColor.class, tc -> System.out.println("tri color: " + tc)
);
рдЖрдЧрдВрддреБрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рд╣рдо рд▓рдХреНрд╖реНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░, рд╢рд╛рдЦрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рд▓рдВрдмреЛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВред public static <V, T1, T2>
void matches(V value,
Class<T1> firstClazz, Consumer<T1> firstBranch,
Class<T2> secondClazz, Consumer<T2> secondBranch) {
verifyExhaustiveness(value, new Class<?>[]{ firstClazz, secondClazz });
Class<?> valueClass = value.getClass();
if (firstClazz == valueClass) {
firstBranch.accept((T1) value);
} else if (secondClazz == valueClass) {
secondBranch.accept((T2) value);
}
}
рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд▓рдХреНрд╖реНрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЙрдкрдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЬрд╛рдирдиреЗ рдФрд░ рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ рдХреБрдЫ рдЙрдкрдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджреЗрдВрдЧреЗредpublic static <V> void verifyExhaustiveness(V value, Class<?>[] inputClasses) {
SealedAttribute data = cacheSubclasses.computeIfAbsent(value.getClass(), SealedAttribute::new);
Class<?>[] subClasses = data.getSubClasses();
StringBuilder builder = new StringBuilder();
boolean flag = false;
if (subClasses.length != inputClasses.length) {
throw new PatternException("Require " + inputClasses.length + " subclasses. " +
"But checked class has " + subClasses.length + " subclasses.");
}
for (Class<?> subClass : subClasses) {
for (Class<?> inputClass : inputClasses) {
if (subClass == inputClass) {
flag = true;
break;
}
}
if (!flag) {
builder.append(subClass).append(",");
}
flag = false;
}
if (builder.length() >= 1) {
throw new PatternException("Must to be exhaustive, add necessary " + builder.toString() +
" branches or else branch instead");
}
}
рддрджрдиреБрд╕рд╛рд░, рд╣рд░ рдмрд╛рд░ рдХреНрд▓рд╛рд╕ рд╕рдмрдЯрд┐рдк рдХреА рдЧрдгрдирд╛ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреИрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдБрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд▓рдХреНрд╖реНрдп рд╡рд░реНрдЧ рд╕рд╛рд░ рд╣реИ, рдПрдХ рдирд┐рдЬреА рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рд╣реИ, рдФрд░ рд╕рднреА рдиреЗрд╕реНрдЯреЗрдб рд╡рд░реНрдЧ рдХреЛ рд▓рдХреНрд╖реНрдп рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИредpublic final class SealedAttribute {
private Class<?>[] subClasses;
public SealedAttribute(Class<?> clazz) {
Class<?> sealedClass = clazz.getSuperclass();
if (!sealedClass.isAnnotationPresent(Sealed.class)) {
throw new PatternException("Checked class must to be mark as sealed");
}
if (!Modifier.isAbstract(sealedClass.getModifiers())) {
throw new PatternException("Checked class must to be abstract");
}
try {
final Constructor<?> constructor = sealedClass.getDeclaredConstructor();
if (!Modifier.isPrivate(constructor.getModifiers())) {
throw new PatternException("Default constructor must to be private");
}
this.subClasses = sealedClass.getClasses();
if (subClasses.length == 0) {
throw new PatternException("Checked class must to has one or more visible subClasses");
}
for (Class<?> subclass : subClasses) {
if (!Modifier.isStatic(subclass.getModifiers())) {
throw new PatternException("Subclass must to be static");
}
if (subclass.getSuperclass() != sealedClass) {
throw new PatternException("Subclass must to inherit from checked class");
}
}
} catch (NoSuchMethodException e) {
throw new PatternException("Checked class must to has default constructor " + e.getMessage());
}
}
public Class<?>[] getSubClasses() {
return subClasses;
}
}
рдЖрдЗрдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓рд┐рдЦреЗрдВ рдФрд░ рдФрд╕рдд рдкрд░ рдорд╛рдкреЗрдВ рдХрд┐ рдЖрдЧрдВрддреБрдХ рдХреА рдирд┐рд╖реНрдкрд╛рджрди рдЧрддрд┐ рдФрд░ рд╢реБрджреНрдз рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦреЗ рдХреЛрдб рдореЗрдВ рдХрд┐рддрдирд╛ рдЕрдВрддрд░ рд╣реИред рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдпрд╣рд╛рдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 3, time = 1)
@Fork(3)
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class UnionPatternBenchmark {
private BiColor biColor;
@Setup
public void setup() {
biColor = new BiColor.Red();
}
@Benchmark
public int matchesSealedBiExpressionPlain() {
if (biColor instanceof BiColor.Red) {
return 0x1;
} else if (biColor instanceof BiColor.Blue) {
return 0x2;
}
return 0x0;
}
@Benchmark
public int matchesSealedBiExpressionReflective() {
return matches(biColor).as(
BiColor.Red.class, r -> 0x1,
BiColor.Blue.class, b -> 0x2
);
}
}
UnionPatternBenchmark.matchesSealedBiExpressionPlain avgt 9 5,992 ┬▒ 0,332 ns/op
UnionPatternBenchmark.matchesSealedTriExpressionPlain avgt 9 7,199 ┬▒ 0,356 ns/op
UnionPatternBenchmark.matchesSealedBiExpressionReflective avgt 9 45,192 ┬▒ 11,951 ns/op
UnionPatternBenchmark.matchesSealedTriExpressionReflective avgt 9 43,413 ┬▒ 0,702 ns/op
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реАрд▓рдмрдВрдж рдкреНрд░рдХрд╛рд░ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╕реБрд╡рд┐рдзрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдмрдирд╛ рджреЗрдЧрд╛редрдЖрдЧрдВрддреБрдХ рдХрд╛ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдЬреАрдердм рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред