рдЬрд╛рд╡рд╛ рдореЗрдВ рд╕реАрд▓ рдкреНрд░рдХрд╛рд░

рдЬрд╛рд╡рд╛ рднрд╛рд╖рд╛ рдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрдиреЗ рдХреА рд╢реБрд░реБрдЖрдд рдХреА рд╣реИред рдЬрд╛рд╡рд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдЫрд╣ рдорд╣реАрдиреЗ рдХреА рд░рд┐рд▓реАрдЬ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЦреБрд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИред

рдЬрд╛рд╡рд╛ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рд╣реИред рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЫреЛрдбрд╝рддреЗ рд╕рдордп рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдврдВрдЧ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддрд╛ рд╣реИред

рдЬрд╛рд╡рд╛ рдореЗрдВ рдкреИрдЯрд░реНрди рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рдкреНрд░рдореБрдЦ рдмреНрд▓реЙрдХ рд░рд┐рдХреЙрд░реНрдб рдФрд░ рд╕реАрд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВред

рд░рд┐рдХреЙрд░реНрдб рдЙрди рд╡рд░реНрдЧреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдирд┐рд░рдВрддрд░, рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЗ рд╕рд░рд▓ рд╡рд╛рд╣рдХ рд╣реИрдВред

рдЬрд╛рд╡рд╛ 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

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реАрд▓рдмрдВрдж рдкреНрд░рдХрд╛рд░ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рд╕реБрд╡рд┐рдзрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдмрдирд╛ рджреЗрдЧрд╛ред

рдЖрдЧрдВрддреБрдХ рдХрд╛ рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб рдЬреАрдердм рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

All Articles