
рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ: рд▓реИрдореНрдмрдбрд╛рдореЗрдЯреЗрдХреНрдЯреИрдХреНрдЯ рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рдХрдо рдЬрд╛рд╡рд╛ рдЬрд╛рд╡рд╛ рддрдВрддреНрд░ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рд╣рдордиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЗрд╕рдХреА рдЦреЛрдЬ рдХреА, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрди рдХреНрд╖рдорддрд╛рдУрдВ рдХреА рд╕рд░рд╛рд╣рдирд╛ рдХреАред CUBA рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рд╡рд░реНрдЬрди 7.0 рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдкреИрджрд╛ рдХрд░рдиреЗ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рд░рд┐рдлреНрд▓реЗрдХреНрдЯрд┐рд╡ рдХреЙрд▓ рд╕реЗ рдмрдЪрдХрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдЗрд╕ рддрдВрддреНрд░ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдПрдиреЛрдЯреЗрд╢рди, рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп, рд╕реНрдкреНрд░рд┐рдВрдЧ рд╕реЗ EventListener рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рджреНрд╡рд╛рд░рд╛ рдЖрд╡реЗрджрди рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдмрдВрдзрдиред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд▓реИрдореНрдмреНрдбрд╛рдлреИрдХреНрдЯрд┐рдВрдЧ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЬреНрдЮрд╛рди рдХрдИ рдЬрд╛рд╡рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдЗрд╕ рдЕрдиреБрд╡рд╛рдж рдХреЛ рдЖрдкрдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдореЗрдВ рдЬрд▓реНрджрдмрд╛рдЬреА рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдЬрд╛рд╡рд╛ 8 рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдФрд░ рдЗрди рдПрдХреНрдЯреНрд░реЗрд╕реЗрд╕ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реБрдП рдХреБрдЫ рдЫреЛрдЯреА-рдЫреЛрдЯреА рдЯреНрд░рд┐рдХреНрд╕ рджрд┐рдЦрд╛рдПрдВрдЧреЗред рд▓реЗрдЦ рдХреЗ рд▓рдХреНрд╖рд┐рдд рджрд░реНрд╢рдХ рд╡рд░рд┐рд╖реНрда рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕, рд╢реЛрдзрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдЯреВрд▓рдХрд┐рдЯ рдбреЗрд╡рд▓рдкрд░реНрд╕ рд╣реИрдВред com.sun.*
рдмрд┐рдирд╛ рдХреЗрд╡рд▓ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЬрд╛рд╡рд╛ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ com.sun.*
рдФрд░ рдЕрдиреНрдп рдЖрдВрддрд░рд┐рдХ рдХрдХреНрд╖рд╛рдПрдВ, рдЗрд╕рд▓рд┐рдП рдХреЛрдб рд╡рд┐рднрд┐рдиреНрди рдЬреЗрд╡реАрдПрдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЗ рдмреАрдЪ рдкреЛрд░реНрдЯреЗрдмрд▓ рд╣реИред
рд╢реЙрд░реНрдЯ рдлреЙрд░рд╡рд░реНрдб
рдЧреБрдордирд╛рдо рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдЬрд╛рд╡рд╛ 8 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП рдФрд░,
рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЕрдирд╛рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВред рдмрд╛рдЗрдЯрдХреЛрдб рд╕реНрддрд░ рдкрд░, рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЛ invokedynamic
рджреНрд╡рд╛рд░рд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдирд┐рд░реНрджреЗрд╢ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдПрдХрдорд╛рддреНрд░ рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд┐рдзрд┐ рдореЗрдВ рджрд░реНрд╢рд╛рддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЛрдб рд╣реЛрддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣реИрдВ:
void printElements(List<String> strings){ strings.forEach(item -> System.out.println("Item = %s", item)); }
рдЗрд╕ рдХреЛрдб рдХреЛ рдЬрд╛рд╡рд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
private static void lambda_forEach(String item) {
invokedynamic
рдирд┐рд░реНрджреЗрд╢ рдХреЛ рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдРрд╕реЗ рдЬрд╛рд╡рд╛ рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
private static CallSite cs; void printElements(List<String> strings) { Consumer<String> lambda;
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, LambdaMetafactory
рдХрд╛ рдЙрдкрдпреЛрдЧ LambdaMetafactory
рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдлреИрдХреНрдЯреНрд░реА рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд▓рдХреНрд╖реНрдп рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реИрдВрдбрд▓рд░ рджреЗрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ invokeExact
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди invokeExact
ред рдпрджрд┐ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд┐рдП рдЧрдП рдЪрд░ рд╣реИрдВ, рддреЛ invokeExact
рдЗрди рдЪрд░ рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред
Oracle JRE 8 рдореЗрдВ, рдореЗрдЯрд╛рдлрд╝реИрдХреНрдЪреБрдЕрд▓реА рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ ObjectWeb Asm рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрд╛рд╡рд╛ рд╡рд░реНрдЧ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдмрдирд╛рдП рдЧрдП рд╡рд░реНрдЧ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдмрд╛рд╣рд░реА рдЪрд░ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЬрд╛рд╡рд╛ рдЧреБрдордирд╛рдо рд╡рд░реНрдЧреЛрдВ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдВрддрд░ рд╣реИрдВ:
- рдПрдХ рдЕрдирд╛рдо рд╡рд░реНрдЧ рдЬрд╛рд╡рд╛ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред
- рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЧ рд░рдирдЯрд╛рдЗрдо рдкрд░ JVM рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдореЗрдЯрд╛рдлреИрдХреНрдЯрд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЗрд╡реАрдПрдо рд╡рд┐рдХреНрд░реЗрддрд╛ рдФрд░ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ
рдмреЗрд╢рдХ, invokedynamic
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреЗрд╡реАрдПрдо рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рджреМрд░рд╛рди рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдиреИрд╢реЙрд░реНрди рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди , рдЬрд┐рд╕реЗ рдЬрд╛рд╡рд╛ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рднрд╛рд░реА рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо LambdaMetafactory
рдХреНрд▓рд╛рд╕ рдФрд░ рдЙрд╕рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд
рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЦрдВрдб рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдореЗрдЯрд╛рдлреИрдХреНрдЯрд┐рдХ рддрд░реАрдХреЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ MethodHandle
рдХреНрдпрд╛ MethodHandle
рд▓рдВрдмреЛрджрд░ рднрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдЯреЛрдЯрдХреЗ
рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ, рд╣рдо рдпрд╣ рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рд▓реИрдореНрдмреНрдбрд╛ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдПред
рдЕрдкрд╡рд╛рджреЛрдВ рдФрд░ рд▓рдВрдмреЛрджрд░ рдХреА рдЬрд╛рдБрдЪ рдХреА
рдпрд╣ рдХреЛрдИ рд░рд╣рд╕реНрдп рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛ рдореЗрдВ рдореМрдЬреВрдж рд╕рднреА рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлреЗрд╕ рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рдБрдЪ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рдлрд╛рдпрджреЗ рдмрд╣реБрдд рд▓рдВрдмреЗ рд╕рдордп рддрдХ (рдФрд░ рдЕрднреА рднреА рдЧрд░реНрдо) рдмрд╣рд╕ рд╣реИрдВред
рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдЖрдкрдХреЛ рдЬрд╛рд╡рд╛ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд╕рдВрдпреЛрдЬрди рдореЗрдВ рд▓реИрдореНрдмрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЗ рдЕрдВрджрд░ рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд╕реВрдЪреА рдХреЛ URL рдХреА рд╕реВрдЪреА рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
Arrays.asList("http://localhost/", "https://github.com").stream() .map(URL::new) .collect(Collectors.toList())
URL (рд╕реНрдЯреНрд░рд┐рдВрдЧ) рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдПрдХ рдлреЗрдВрдХрдиреЗ рдпреЛрдЧреНрдп рдЕрдкрд╡рд╛рдж рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╕реАрдзреЗ рдлрдВрдХреНрд╢рдирд▓ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЖрдк рдХрд╣реЗрдВрдЧреЗ: "рдирд╣реАрдВ, рд╢рд╛рдпрдж рдЕрдЧрд░ рдЖрдк рдЗрд╕ рдЯреНрд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдВ рдХрд░рддреЗ рд╣реИрдВ":
public static <T> T uncheckCall(Callable<T> callable) { try { return callable.call(); } catch (Exception e) { return sneakyThrow(e); } } private static <E extends Throwable, T> T sneakyThrow0(Throwable t) throws E { throw (E)t; } public static <T> T sneakyThrow(Throwable e) { return Util.<RuntimeException, T>sneakyThrow0(e); }
рдпрд╣ рдПрдХ рдЧрдВрджреА рд╣реИрдХ рд╣реИред рдФрд░ рдпрд╣рд╛рдБ рдХреНрдпреЛрдВ рд╣реИ:
- рдЯреНрд░рд╛рдЗ-рдХреИрдЪ рдмреНрд▓реЙрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдЕрдкрд╡рд╛рдж рдлрд┐рд░ рд╕реЗ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдЬрд╛рд╡рд╛ рдореЗрдВ рдЯрд╛рдЗрдк рдЗрд░реЗрдЬрд╝рд░ рдХрд╛ рдЧрдВрджрд╛ рдЙрдкрдпреЛрдЧред
рд╕рдорд╕реНрдпрд╛ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ "рдХрд╛рдиреВрдиреА" рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрдереНрдпреЛрдВ рдХреЗ рдЬреНрдЮрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ:
- рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рдж рдЬрд╛рд╡рд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реНрддрд░ рдкрд░ рд╣реА рдкрд╣рдЪрд╛рдиреЗ рдЬрд╛рддреЗ рд╣реИрдВред
throws
рд╕реЗрдХреНрд╢рди рдЬреЗрд╡реАрдПрдо рд╕реНрддрд░ рдкрд░ рд╕рд┐рдореЗрдВрдЯрд┐рдХ рд╡реИрд▓реНрдпреВ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╕рд┐рд░реНрдл рдореЗрдЯрд╛рдбреЗрдЯрд╛ рд╣реИред- рдЬрд╛рдБрдЪ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдЕрдкрд╡рд╛рдж JVM рдореЗрдВ рдмрд╛рдЗрдЯрдХреЛрдб рд╕реНрддрд░ рдкрд░ рдЕрдкреНрд░рднреЗрджреНрдп рд╣реИрдВред
рд╕рдорд╛рдзрд╛рди throws
рдЦрдВрдб рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╡рд┐рдзрд┐ рдореЗрдВ Callable.call
рд╡рд┐рдзрд┐ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ:
static <V> V callUnchecked(Callable<V> callable){ return callable.call(); }
рдпрд╣ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ Callable.call
рдкрджреНрдзрддрд┐ Callable.call
throws
рдЦрдВрдб рдореЗрдВ рдЬрд╛рдБрдЪ рдЕрдкрд╡рд╛рдж рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдорд┐рдд рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ throws
рд╕реЗрдХреНрд╢рди рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдХреМрди Callable.call
рдХреЙрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХрд░ рдкрд╛рдПрдЧрд╛:
@FunctionalInterface interface SilentInvoker { MethodType SIGNATURE = MethodType.methodType(Object.class, Callable.class);
рджреВрд╕рд░рд╛ рдХрджрдо рд╣реИ LambdaMetafactory
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ LambdaMetafactory
рдФрд░ SilentInvoker.invoke
рд╡рд┐рдзрд┐ рдХреЛ SilentInvoker.invoke
рд╡рд┐рдзрд┐ рдХрд╛ рдХреЙрд▓ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХрд░рдирд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, SilentInvoker.invoke
рдХреЛ SilentInvoker.invoke
рд╕реНрддрд░ рдкрд░ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП SilentInvoker.invoke
рд╡рд┐рдзрд┐ рдЕрдкрд╡рд╛рдж рдШреЛрд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ Callable.call
рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреА рд╣реИ:
private static final SilentInvoker SILENT_INVOKER; final MethodHandles.Lookup lookup = MethodHandles.lookup(); final CallSite site = LambdaMetafactory.metafactory(lookup, "invoke", MethodType.methodType(SilentInvoker.class), SilentInvoker.SIGNATURE, lookup.findVirtual(Callable.class, "call", MethodType.methodType(Object.class)), SilentInvoker.SIGNATURE); SILENT_INVOKER = (SilentInvoker) site.getTarget().invokeExact();
рддреАрд╕рд░рд╛, рд╣рдо рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдЕрдкрд╡рд╛рдж рдШреЛрд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ Callable.call
рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ:
public static <V> V callUnchecked(final Callable<V> callable) { return SILENT_INVOKER.invoke(callable); }
рдЕрдм рдЖрдк рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрд┐рдирд╛ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
Arrays.asList("http://localhost/", "https://dzone.com").stream() .map(url -> callUnchecked(() -> new URL(url))) .collect(Collectors.toList());
рдпрд╣ рдХреЛрдб рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ callUnchecked
рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдореЛрдиреЛрдореЛрд░реНрдлрд┐рдХ рдЗрдирд▓рд╛рдЗрди рдХреИрд╢рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдирд▓рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкреВрд░реЗ рдЬреЗрд╡реАрдПрдо рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ SilentOnvoker
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ
рдпрджрд┐ Callable.call
рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд░рди рд╕рдордп рдореЗрдВ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдХреЙрд▓рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ Callable.call
рдЬрд╛рдПрдЧрд╛:
try{ callUnchecked(() -> new URL("Invalid URL")); } catch (final Exception e){ System.out.println(e); }
рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрд╢рдВрд╕рд╛ рдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:
рдХреЙрд▓ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдЪреЗрдХ рдХрд┐рдП рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдЫрд┐рдкрд╛рдПрдВ рдХреЗрд╡рд▓ рдпрджрд┐ рдЖрдк рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВ рдХрд┐ рдХреЙрд▓ рдХреЛрдб рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рдлреЗрдВрдХреЗрдВрдЧреЗ
рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рддрд╛ рд╣реИ:
callUnchecked(() -> new URL("https://dzone.com"));
рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпрд╣рд╛рдВ рд╣реИ , рдпрд╣ SNAMP рдУрдкрди рд╕реЛрд░реНрд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред
рдЧреЗрдЯрд░реНрд╕ рдПрдВрдб рд╕реЗрдЯрд░реНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛
рдпрд╣ рдЕрдиреБрднрд╛рдЧ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдбреЗрдЯрд╛ рдкреНрд░рд╛рд░реВрдкреЛрдВ рдЬреИрд╕реЗ рдХрд┐ JSON, рдереНрд░рд┐рдлреНрдЯ, рдЗрддреНрдпрд╛рджрд┐ рдХреЗ рд▓рд┐рдП рдХреНрд░рдорд╛рдВрдХрди / deserialization рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдкрдХрд╛ рдХреЛрдб JavaBeans рдореЗрдВ рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рдЬрд╛рд╡рд╛рдмреАрди рдореЗрдВ рдШреЛрд╖рд┐рдд рдПрдХ рдЧреЗрдЯрдЯрд░ рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдирд╛рдо getXXX
рдЬрд┐рд╕рдореЗрдВ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИ рдФрд░ void
рдЕрд▓рд╛рд╡рд╛ рдПрдХ рд░рд┐рдЯрд░реНрди рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИред рдЬрд╛рд╡рд╛рдмреАрди рдореЗрдВ рдШреЛрд╖рд┐рдд рдПрдХ setXXX
рдирд╛рдордХ рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рд░рд┐рдЯрд░реНрдирд┐рдВрдЧ void
ред рдЗрди рджреЛ рд╕реВрдЪрдирд╛рдУрдВ рдХреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рдЧреЗрдЯреНрдЯрд░ рдХреЛ рдлрдВрдХреНрд╢рди рдХреНрд▓рд╛рд╕ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рддрд░реНрдХ рдЗрд╕ рдХрд╛ рдореВрд▓реНрдп рд╣реИред
- рд╕реЗрдЯрд░ рдХреЛ BiConsumer рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрд╣рд▓рд╛ рддрд░реНрдХ
this
, рдФрд░ рджреВрд╕рд░рд╛ рд╡рд╣ рдорд╛рди рд╣реИ рдЬреЛ рд╕реЗрдЯрд░ рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЕрдм рд╣рдо рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдБ рдмрдирд╛рдПрдБрдЧреЗ рдЬреЛ рдХрд┐рд╕реА рднреА рдЧреЗрдЯреНрдЯрд░ рдпрд╛ рд╕реЗрдЯрд░ рдХреЛ рдЗрди рдореЗрдВ рдмрджрд▓ рд╕рдХрддреА рд╣реИрдВ
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлреЗрд╕ред рдФрд░ рдпрд╣ рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рдХрд┐ рджреЛрдиреЛрдВ рдЗрдВрдЯрд░рдлреЗрд╕ рдЬреЗрдирд░рд┐рдХ рд╣реИрдВред рдкреНрд░рдХрд╛рд░ рдорд┐рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рдж
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ Object
рд╣реЛрдЧрд╛ред LambdaMetafactory
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдФрд░ рддрд░реНрдХреЛрдВ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдорд░реБрдж рдкреБрд╕реНрддрдХрд╛рд▓рдп рдПрдХ рд╣реА рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рд▓реИрдореНрдмреНрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреА рдорджрдж рдХрд░реЗрдЧрд╛ред
рдкрд╣рд▓рд╛ рдХрджрдо: рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдХреИрд╢ рдмрдирд╛рдПрдВред рдкрд░рд╛рд╡рд░реНрддрди рдПрдкреАрдЖрдИ рдХреА рд╡рд┐рдзрд┐ рд╡рд░реНрдЧ рдПрдХ рдЕрд╕рд▓реА рдЧреЗрдЯреНрдЯрд░ рдпрд╛ рд╕реЗрдЯрд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреИрд╢ рдорд╛рди рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЧреЗрдЯреНрдЯрд░ рдпрд╛ рд╕реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдорд┐рдд рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИред
private static final Cache<Method, Function> GETTERS = CacheBuilder.newBuilder().weakValues().build(); private static final Cache<Method, BiConsumer> SETTERS = CacheBuilder.newBuilder().weakValues().build();
рджреВрд╕рд░реЗ, рд╣рдо рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдХрд┐ рдЧрдЯрд░ рдпрд╛ рд╕реЗрдЯрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВред
private static Function createGetter(final MethodHandles.Lookup lookup, final MethodHandle getter) throws Exception{ final CallSite site = LambdaMetafactory.metafactory(lookup, "apply", MethodType.methodType(Function.class), MethodType.methodType(Object.class, Object.class),
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлреЗрд╕ (рдЯрд╛рдЗрдк рдПрд░рд╛рд╕реБрд░реЗ рдХреЗ рдмрд╛рдж) рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдФрд░ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдореЗрдВ Object
рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреНрд░рдХрд╛рд░ рд░реВрдкрд╛рдВрддрд░рдг samMethodType
рдФрд░ samMethodType
(рдХреНрд░рдорд╢рдГ, рдореЗрдЯрд╛рдлреИрдХреНрдЯ рд╡рд┐рдзрд┐ рдХреЗ рддреАрд╕рд░реЗ рдФрд░ рдкрд╛рдВрдЪрд╡реЗрдВ рддрд░реНрдХ) рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд┐рдзрд┐ рдХреЗ рдмрдирд╛рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдкреНрд░рдХрд╛рд░ - рдпрд╣ рдЙрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╣реИ рдЬреЛ рд▓рдВрдмреЛрджрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рддреАрд╕рд░рд╛, рд╣рдо рдЗрди рдлреИрдХреНрдЯрд░рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреИрд╢рд┐рдВрдЧ рдХреЗ рд╕рдорд░реНрдерди рд╕реЗ рдПрдХ рдореБрдЦреМрдЯрд╛ рдмрдирд╛рдПрдВрдЧреЗ:
public static Function reflectGetter(final MethodHandles.Lookup lookup, final Method getter) throws ReflectiveOperationException { try { return GETTERS.get(getter, () -> createGetter(lookup, lookup.unreflect(getter))); } catch (final ExecutionException e) { throw new ReflectiveOperationException(e.getCause()); } } public static BiConsumer reflectSetter(final MethodHandles.Lookup lookup, final Method setter) throws ReflectiveOperationException { try { return SETTERS.get(setter, () -> createSetter(lookup, lookup.unreflect(setter))); } catch (final ExecutionException e) { throw new ReflectiveOperationException(e.getCause()); } }
рдЬрд╛рд╡рд╛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Method
рд╡рд░реНрдЧ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╡рд┐рдзрд┐ рдЬрд╛рдирдХрд╛рд░реА рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ MethodHandle
рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ MethodHandle
ред рдЗрд╕ рдмрд╛рдд рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ рдХрд┐ рдХрдХреНрд╖рд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдПрдХ рдЫрд┐рдкрд╛ рд╣реБрдЖ рдкрд╣рд▓рд╛ рддрд░реНрдХ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реНрдЯреИрдЯрд┐рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдРрд╕рд╛ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Integer.intValue()
рдкрджреНрдзрддрд┐ рдХрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ int intValue(Integer this)
рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред рдЗрд╕ рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЖрд╡рд░рдг рдХреЗ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдФрд░ рдЕрдм рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ:
final Date d = new Date(); final BiConsumer<Date, Long> timeSetter = reflectSetter(MethodHandles.lookup(), Date.class.getDeclaredMethod("setTime", long.class)); timeSetter.accept(d, 42L);
рдХреИрд╢реНрдб рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдХреНрд░рдорд╛рдВрдХрди / рдбрд┐рд╕реЗрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдЬреИрд╕реЗ рдЬреИрдХреНрд╕рди) рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХреНрд░рдорд╛рдВрдХрди рдФрд░ рдбреАрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
LambdaMetaFactory
рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЬрд╛рд╡рд╛ рдкрд░рд╛рд╡рд░реНрддрди рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ LambdaMetaFactory
рдХрд╛рдлреА рддреЗрдЬ рд╣реИ
рдХреЛрдб рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ , рдпрд╣ SNAMP рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред
рд╕реАрдорд╛рдПрдБ рдФрд░ рдХреАрдбрд╝реЗ
рдЗрд╕ рдЦрдВрдб рдореЗрдВ, рд╣рдо рдЬрд╛рд╡рд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рдФрд░ рдЬреЗрд╡реАрдПрдо рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рд╕реЗ рдЬреБрдбрд╝реЗ рдХреБрдЫ рдмрдЧ рдФрд░ рд╕реАрдорд╛рдУрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред рдЗрди рд╕рднреА рд╕реАрдорд╛рдУрдВ рдХреЛ OpenJDK рдФрд░ Oracle JDK рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдФрд░ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП javac
рд╕рдВрд╕реНрдХрд░рдг 1.8.0_131 рдХреЗ рд╕рд╛рде рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡рд┐рдзрд┐ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рд╕реЗ рд▓рдВрдмреЛрджрд░ рднрд╛рд╡ рдмрдирд╛рдирд╛
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рд▓реИрдореНрдмреНрдбрд╛рдореИрдЯрд╛рдлреИрдХреНрдЯрд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рд╣реИрдВрдбрд▓рд░ - MethodHandle
рдХреНрд▓рд╛рд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдПрдХрдорд╛рддреНрд░ рд╡рд┐рдзрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:
final class TestClass { String value = ""; public String getValue() { return value; } public void setValue(final String value) { this.value = value; } } final TestClass obj = new TestClass(); obj.setValue("Hello, world!"); final MethodHandles.Lookup lookup = MethodHandles.lookup(); final CallSite site = LambdaMetafactory.metafactory(lookup, "get", MethodType.methodType(Supplier.class, TestClass.class), MethodType.methodType(Object.class), lookup.findVirtual(TestClass.class, "getValue", MethodType.methodType(String.class)), MethodType.methodType(String.class)); final Supplier<String> getter = (Supplier<String>) site.getTarget().invokeExact(obj); System.out.println(getter.get());
рдпрд╣ рдХреЛрдб рдЗрд╕рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:
final TestClass obj = new TestClass(); obj.setValue("Hello, world!"); final Supplier<String> elementGetter = () -> obj.getValue(); System.out.println(elementGetter.get());
рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рд╡рд┐рдзрд┐ рд╣реИрдВрдбрд▓рд░ рдХреА рдЬрдЧрд╣ рд▓реЗрддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде getValue
рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЧреЗрдЯреНрдЯрд░ рдлрд╝реАрд▓реНрдб рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ:
final CallSite site = LambdaMetafactory.metafactory(lookup, "get", MethodType.methodType(Supplier.class, TestClass.class), MethodType.methodType(Object.class), lookup.findGetter(TestClass.class, "value", String.class),
рдпрд╣ рдХреЛрдб, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛, рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ findGetter
рдПрдХ рд╣реИрдВрдбрд▓рд░ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдЧреЗрдЯрд░ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕рд╣реА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реИред рд▓реЗрдХрд┐рди, рдпрджрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдирд┐рдореНрди рдЕрдкрд╡рд╛рдж рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреЗ:
java.lang.invoke.LambdaConversionException: Unsupported MethodHandle kind: getField
рдпрджрд┐ рд╣рдо MethodHandleProxies рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЧреЗрдЯреНрдЯрд░ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
final Supplier<String> getter = MethodHandleProxies .asInterfaceInstance(Supplier.class, lookup.findGetter(TestClass.class, "value", String.class) .bindTo(obj));
рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ MethodHandleProxies
рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ MethodHandleProxies
рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд░реНрдЧ рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░реЙрдХреНрд╕реА рд╡рд░реНрдЧ рдореЗрдВ MethodHandle
рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ рдФрд░ invocationHandler.invoke рдХреЛ MethodHandle.vokeWithArguments рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ ред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЬрд╛рд╡рд╛ рд░рд┐рдлреНрд▓реЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрд╣реБрдд рдзреАрдорд╛ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рд▓реИрдореНрдмрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдореЗрдердб рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреЗрд╡рд▓ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдзрд┐ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд▓рдВрдмреЛрджрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рд╡реЗ рд╣реИрдВ:
- REF_invokeInterface: рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП Lookup.findVirtual рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
- REF_invokeVirtual: рдХреНрд▓рд╛рд╕ рд╡рд░реНрдЪреБрдЕрд▓ рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП Lookup.findVirtual рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
- REF_invokeStatic: рд╕реНрдерд┐рд░ рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП Lookup.findStatic рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛
- REF_newInvokeSpecial: рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП Lookup.findConstructor рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
- REF_invokeSpecial: Lookup.findSpecial рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
рдирд┐рдЬреА рддрд░реАрдХреЛрдВ рдФрд░ рдХрдХреНрд╖рд╛ рдЖрднрд╛рд╕реА рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрддреА рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЗ рд▓рд┐рдП
рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реИрдВрдбрд▓рд░ LambdaConversionException
рддреНрд░реБрдЯрд┐ рдХреЛ LambdaConversionException
рджреЗрдВрдЧреЗред
рд╕рд╛рдорд╛рдиреНрдп рдЕрдкрд╡рд╛рдж
рдпрд╣ рдмрдЧ рдЬрд╛рд╡рд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рдФрд░ throws
рд╕реЗрдХреНрд╢рди рдореЗрдВ рдЬреЗрдиреЗрд░рд┐рдХ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдирд┐рдореНрди рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:
interface ExtendedCallable<V, E extends Exception> extends Callable<V>{ @Override V call() throws E; } final ExtendedCallable<URL, MalformedURLException> urlFactory = () -> new URL("http://localhost"); urlFactory.call();
рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ URL
рд╡рд░реНрдЧ рдХрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рдПрдХ MalformedURLException
рдлреЗрдВрдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдирд┐рдореНрди рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИ:
Error:(46, 73) java: call() in <anonymous Test$CODEgt; cannot implement call() in ExtendedCallable overridden method does not throw java.lang.Exception
рд▓реЗрдХрд┐рди, рдЕрдЧрд░ рд╣рдо рд▓реИрдореНрдмрдбрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЛ рдПрдХ рдЕрдирд╛рдо рд╡рд░реНрдЧ рд╕реЗ рдмрджрд▓ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:
final ExtendedCallable<URL, MalformedURLException> urlFactory = new ExtendedCallable<URL, MalformedURLException>() { @Override public URL call() throws MalformedURLException { return new URL("http://localhost"); } }; urlFactory.call();
рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
рдЬреЗрдиреЗрд░рд┐рдХ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирд┐рд╖реНрдХрд░реНрд╖ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ
рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реАрдорд╛рдПрдВ
рдЖрдк &
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд╕реНрддреБ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: <T extends A & B & C & ... Z>
рдЪрд┐рд╣реНрди рд╣реИред
рдЬреЗрдиреЗрд░рд┐рдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рдХреБрдЫ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рдХрд╛рд░рдг рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рдВрдмреЛрджрд░ рднрд╛рд╡ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ:
- рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдмрд╛рдзрд╛, рдкрд╣рд▓реЗ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдРрд╕реА рдЬреЗрдиреЗрд░рд┐рдХ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рд╢реБрджреНрдз рд╕рдВрд╕реНрдХрд░рдг рдХреЗрд╡рд▓ рд╕реВрдЪреА рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рдХрд╛рд░ рдХреА рдмрд╛рдзрд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддрд╛ рд╣реИред
рджреВрд╕рд░реА рд╕реАрдорд╛ рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдФрд░ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдХреЛрдб рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╡реНрдпрд╡рд╣рд╛рд░реЛрдВ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИ, рдЬрдм рд▓рдВрдмреЛрджрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рд╣реЛрддреА рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдЕрдВрддрд░ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
final class MutableInteger extends Number implements IntSupplier, IntConsumer {
рдпрд╣ рдХреЛрдб рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА рд╣реИ рдФрд░ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдХрд▓рди рдХрд░рддрд╛ рд╣реИред MutableInteger
рд╡рд░реНрдЧ рдЬреЗрдиреЗрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ T рдХреА рдмрд╛рдзрд╛рдУрдВ рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ:
MutableInteger
Number
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИредMutableInteger
рд▓рд╛рдЧреВ IntSupplier
ред
рд▓реЗрдХрд┐рди рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдХреЛрдб рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рдПрдЧрд╛:
java.lang.BootstrapMethodError: call site initialization exception at java.lang.invoke.CallSite.makeSite(CallSite.java:341) at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307) at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297) at Test.minValue(Test.java:77) Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Number; not a subtype of implementation type interface java.util.function.IntSupplier at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233) at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303) at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ JavaStream рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреЗрд╡рд▓ рдПрдХ рд╢реБрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрдХрдбрд╝рддреА рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, Number
рд╡рд░реНрдЧ рд╣реИ рдФрд░ рдпрд╣ IntSupplier
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдЕрд▓рдЧ рд╡рд┐рдзрд┐ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдШреЛрд╖рд┐рдд рдХрд░рдХреЗ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рдзрд┐ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
private static int getInt(final IntSupplier i){ return i.getAsInt(); } private static <T extends Number & IntSupplier> OptionalInt findMinValue(final Collection<T> values){ return values.stream().mapToInt(UtilsTest::getInt).min(); }
рдпрд╣ рдЙрджрд╛рд╣рд░рдг рд╕рдВрдХрд▓рдХ рдФрд░ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдФрд░ рд░рдирдЯрд╛рдЗрдо рдкрд░ рд▓реИрдореНрдмреНрдбрд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдХрдИ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рд╕реБрд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИ