рдЗрд╕рдХреЗ рдмрджрд▓реЗ "рд╕рдорд░реНрдкрд┐рдд ..."
рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рдХрд╛рд░реНрдп рдЕрднрд┐рдирд╡ рдпрд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рдерд╛, рдЬрд┐рд╕ рдХрдВрдкрдиреА рдореЗрдВ рдореИрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВ, рдЙрд╕реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рд▓рд╛рдн рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рдмреЛрдирд╕ рд╣реЛрдЧрд╛ред
рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рд░реНрдп рдерд╛, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдерд╛ред
рдкрд╣рдЪрд╛рди
рд▓реЗрдЦ рдореЗрдВ рдЖрдк рдЕрдХреНрд╕рд░ рд▓реЛрдореНрдмреЛрдХ рд╢рдмреНрдж рд╕реЗ рдорд┐рд▓реЗрдВрдЧреЗ, рдореИрдВ рдирдлрд░рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рд╕реЗ рдирд┐рд╖реНрдХрд░реНрд╖ рдкрд░ рдирд╣реАрдВ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реВрдВред
рдореИрдВ рд▓реЛрдореНрдмреЛрдХ рдпрд╛ рдЙрд╕рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП "рдбреВрдмрдиреЗ" рдирд╣реАрдВ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ, рдореИрдВ, рдЧреЗрд░рд╛рд▓реНрдЯ рд╕рдкрдХреЛрд╡реНрд╕реНрдХреА рдХреА рддрд░рд╣, рддрдЯрд╕реНрде рд░рд╣рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдореИрдВ рд╢рддрд╛рдмреНрджреА рдореЗрдВ рдпрд╛ рдмрд┐рдирд╛ рдФрд░ рдмрд┐рдирд╛ рд▓реЛрдХреЛрдм рдХреЗ рд╢рд╛рдВрддрд┐ рдХреЗ рд╕рд╛рде рдХреЛрдб рдкрдврд╝ рд╕рдХрддрд╛ рд╣реВрдВред
рд▓реЗрдХрд┐рди рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░, рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореМрдЬреВрдж рд╣реИ, рдФрд░ рдХреБрдЫ рдореБрдЭреЗ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдирд╣реАрдВ рд╣реИред
рддреЛ рдпрд╣рд╛рдБ рд╣реИред
рдЬрд╛рд╡рд╛ рдореЗрдВ рдЕрдВрддрд┐рдо рдмрд╛рд░ рдПрдиреЛрдЯрд╢рдХреА рдХреА рдУрд░ рдПрдХ рдкреНрд░рд╡реГрддреНрддрд┐ рд╣реИред рддреЗрдЬреА рд╕реЗ рдЕрд╕рдлрд▓ рд╣реЛрдиреЗ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреА рдорд╣рд┐рдорд╛ рдХреЗ рд▓рд┐рдП, рддрд░реАрдХреЛрдВ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЕрдХреНрд╕рд░ рдПрдиреЛрдЯреЗрд╢рди @ рдиреЛрдирд▓ рдХреЗ рд╕рд╛рде рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рддрд╛рдХрд┐ рдЕрдЧрд░ рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЬрд╛рдП, рддреЛ рдпрд╣ рдкрддрд╛
рдЪрд▓рд╛ )ред
рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЖрдпрд╛рдд рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ (рдпрд╛ рд╡рд┐рдЪрд╛рд░рдзрд╛рд░рд╛ рдореЗрдВ рд╕рдорд╛рди рд╡реНрдпрд╛рдЦреНрдпрд╛), рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╣реА рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЪреБрдХрд╛ рд╣реИ, рд╣рдо рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ
import lombok.NonNull;
рдпрджрд┐ рдЖрдк рдЗрд╕ (рдпрд╛ рд╕рдорд╛рди) рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рдЕрдиреБрдмрдВрдз рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдЬрд╛рдВрдЪрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдХреЛрдИ рднреА рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреГрдкрдпрд╛ рдЖрдкрдХреЛ рдмрддрд╛рдПрдЧрд╛ (рд╕реЛрдирд╛рд░ рдЖрдкрдХреЛ рдмрд┐рд▓реНрдХреБрд▓ рдмрддрд╛рддрд╛ рд╣реИ)ред
рдПрдХ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдЗрд╕ рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рд╡рд╕рдВрдд рдореЗрдВ рдЦрд░рдЧреЛрд╢реЛрдВ рдХреА рдЧрддрд┐ рд╕реЗ рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЧреБрдгрд╛ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЦрд░рдЧреЛрд╢, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, DRY рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддреЗ рд╣реИрдВред
рд▓реЗрдЦ рдореЗрдВ рд╣рдо @NonNull рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рдЕрдиреБрдмрдВрдз рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкрд░реАрдХреНрд╖рдг рдврд╛рдБрдЪрд╛ рд▓рд┐рдЦреЗрдВрдЧреЗ (рдФрд░ рддрд╛рдХрд┐ рд╕реЛрдирд╛рд░ рдЖрдкрдХреА рдЖрдБрдЦреЛрдВ рдореЗрдВ рд▓рд╛рд▓рд┐рдорд╛ рди рдмрд┐рдЦреЗрд░реЗ)ред
PS рдЧреАрдд рдХрд╛ рдирд╛рдо рдкреЙрд╡рд░рд╡реЙрд▓реНрдл рдмреИрдВрдб рдХреЗ рдЧреАрдд рд╕реЗ рдкреНрд░реЗрд░рд┐рдд рдерд╛, рдЬреЛ рдореИрдВрдиреЗ (рдореВрд▓ рд░реВрдк рд╕реЗ) рд▓рд┐рдЦрд╛ рдерд╛, рдЬрдм рдореИрдВрдиреЗ рдирд╛рдо рд▓рд┐рдЦрд╛ рдерд╛ (рдореВрд▓ рдореЗрдВ, рдирд╛рдо рдЕрдзрд┐рдХ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд▓рдЧрддрд╛ рд╣реИ)
рдореБрдЦреНрдп рд╢рд░реАрд░
рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рд╣рдордиреЗ рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд┐рдпрд╛:
@Test void methodNameWithNullArgumentThrowException() { try { instance.getAnyType(null); fail("Exception not thrown"); } catch (final NullPointerException e) { assertNotNull(e); } }
рдЙрдиреНрд╣реЛрдВрдиреЗ рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдФрд░ @NonNull рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдиреЛрдЯреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд┐рдпрд╛ред
рдЙрдиреНрд╣реЗрдВ рдПрдирдкреАрдИ рдорд┐рд▓рд╛ рдФрд░ рд╡реЗ рд╕рдВрддреБрд╖реНрдЯ рд╣реБрдП (рд╕реЛрдирд╛рд░ рднреА рдЦреБрд╢ рдереЗ)ред
рдлрд┐рд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдРрд╕рд╛ рд╣реА рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдлреИрд╢рдиреЗрдмрд▓ рдореБрдЦрд░ рдХреЗ рд╕рд╛рде рдЬреЛ рдЖрдкреВрд░реНрддрд┐рдХрд░реНрддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рд╣рдо рд▓рдВрдмреЛрджрд░ рд╕реЗ рдкреНрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ):
@TestUnitRepeatOnce void methodNameWithNullArgumentThrowException() { assertThrows(NullPointerException.class, () -> instance.getAnyType(null)); }
рд╕реНрдЯрд╛рдЗрд▓рд┐рд╢ред рдлреИрд╢рдиреЗрдмрд▓ред рдпреБрд╡рд╛ред
рдпрд╣ рдЦрддреНрдо рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдЕрдзрд┐рдХ рд╣реИ?
рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рдХреА рд╕рдорд╕реНрдпрд╛ (рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрднреА рднреА) "рд╕рд╛рдордиреЗ" рдЬрдм рдПрдХ рджрд┐рди рдореИрдВрдиреЗ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрд╛, рддреЛ рдпрд╣ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рдо рдХрд┐рдпрд╛, рдФрд░ рдлрд┐рд░ рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдХреЛрдИ @ рдиреЛрдирд▓ рдПрдиреЛрдЯреЗрд╢рди рдирд╣реАрдВ рд╣реИред
рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ: рдЖрдк рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдЬрдм () / рддрдм () рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдореВрдХ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдзрд╛рдЧрд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд╡рд┐рдзрд┐ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИ, рдХрд╣реАрдВ рди рдХрд╣реАрдВ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдПрдирдкреАрдИ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рдПрдХ рдЕрдирд▓реЙрдХ (рдпрд╛ рд▓реЙрдХ, рд▓реЗрдХрд┐рди рдмрд┐рдирд╛ () / рддрдм) рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдмрд┐рдирд╛, рдФрд░ рдХреНрд░реИрд╢, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдирдкреАрдИ рдХреЗ рд╕рд╛рде, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдЪреЗрддрд╛рд╡рдиреА рджреА рдереА, рдЬрд┐рд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╣рд░рд╛ рд╣реИ
рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдПрдиреЛрдЯреЗрд╢рди рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдг рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рддрдХ рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдереНрд░реЗрд╢реЛрд▓реНрдб рдкрд░ рдЧрд┐рд░рддреЗ рд╣реБрдП)ред
@ рд▓реЛрдиреЛрдХ рдХреЗ рдПрдирдиреЙрд▓ рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ: рдпрджрд┐ рд╣рдо рдПрдирдкреАрдИ рд╕реЗ рдПрдиреЛрдЯреЗрд╢рди рддрдХ рдЖрддреЗ рд╣реИрдВ, рддреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо рддреНрд░реБрдЯрд┐ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╣рдо рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ, рдЬрдм рд╣рдо рдПрдирдкреАрдИ рд╕реЗ рдЧрд┐рд░ рдЬрд╛рддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рдж рд╕реНрдЯреИрдХрдЯреНрд░реЗрд╕ рдХреЗ рдкрд╛рда рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ, рдЬреИрд╕реЗ:
exception.getCause().getMessage().equals(parameter.getName())
рдФрд░ рдЕрдЧрд░ рдЕрдЪрд╛рдирдХ ...рдЕрдЧрд░ рд▓реЛрдореНрдмреЛрдХ рдЕрдЪрд╛рдирдХ рд░рд┐рдлреНрд░реЗрд╢ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╕реНрдЯреИрдХрдЯреНрд░реЗрд╕ рдореЗрдВ рдЕрд╢рдХреНрдд рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдирд╛рдо рд▓рд┐рдЦрдирд╛ рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИ, рддреЛ рд╣рдо
рдЬреЗрд╡реАрдПрдо рдЯреАрдЖрдИ рдкрд░ рдЖрдВрджреНрд░реЗрдИ рдкреИрдВрдЧрд┐рди рдХреЗ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЬреЗрд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧ-рдЗрди рд▓рд┐рдЦреЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо рднреА рдкрд╛рд╕ рд╣реЛрдЧрд╛ред
рд╕рдм рдХреБрдЫ рдХреБрдЫ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рдЕрдм рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЬрд░реВрд░рдд рд╣реИ, рд▓реЗрдХрд┐рди "рдЦрд░рдЧреЛрд╢" рдХреА рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реБрдИ рд╣реИред
рдореИрдВ рдПрдХ рдРрд╕рд╛ рдЙрдкрдХрд░рдг рд▓реЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЬрд┐рд╕реЗ рдХрд╣рд╛ рдЬрд╛ рд╕рдХреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:
@TestUnitRepeatOnce @SneakyThrows void nonNullAnnotationTest() { assertNonNullAnnotation(YourPerfectClass.class); }
рдФрд░ рд╡рд╣ рд╕реНрд╡рдпрдВ рдЬрд╛рдХрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╡рд░реНрдЧ рдХреЗ рд╕рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЛрдВ рдХреЛ рд╕реНрдХреИрди рдХрд░реЗрдЧрд╛ рдФрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рд╕рднреА @NonNull рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ред
рдЖрдк рдХрд╣реЗрдВрдЧреЗ, рдПрдХ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рдФрд░ рдЬрд╛рдВрдЪ рд▓реЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╡рд┐рдзрд┐ @ рдиреЛрдирд▓ рдЪрд╛рд▓реВ рд╣реИ рдФрд░ рдпрджрд┐ рдЗрд╕рдореЗрдВ рдХреЛрдИ рдЧреЛрд▓реА рд╣реИ рдпрд╛ рдирд╣реАрдВред
рд╕рднреА рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди RetentionPolicy рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИред
рд╕рднреА рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рдПрдХ рд░рд┐рдЯреЗрдВрд╢рдирдкреЙрд▓рд┐рд╢ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ 3 рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: SOURCE, CLASS рдФрд░ RUNTIME, рдЗрд╕рд▓рд┐рдП рд▓реЛрдореНрдмреЛрдХ рдореЗрдВ RetentionPolicy.SOURCE рд╣реИ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдПрдиреЛрдЯреЗрд╢рди рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЖрдк рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреЗред
рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЖрджрд┐рдореЛрдВ рдХреА рдЧрд┐рдирддреА рдирд╣реАрдВ), рдЕрдЧрд░ рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рд╢реВрдиреНрдп рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрджрд┐ рд╡рд┐рдкрд░реАрдд рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╕рдВрдд @ рдПрдиреБрд▓реНрдмрд▓ рджреНрд╡рд╛рд░рд╛ рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рд╕рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЙрдирдореЗрдВ рд╕рднреА рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛ @Nullable рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рд╣реИрдВ рдФрд░ рдЖрджрд┐рдо рдирд╣реАрдВ рд╣реИрдВред
рд╣рдорд╛рд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЕрдиреНрдп рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдиреЛрдЯреЗрд╢рди @NonNull рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдЬрдм рднреА рд╕рдВрднрд╡ рд╣реЛ, рд╣рдо рдирд┐рдЬреА рддрд░реАрдХреЛрдВ рд╕реЗ рддрд░реНрдХ рдлреИрд▓рд╛рдПрдВрдЧреЗ, рдПрдХ рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рд╕рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЗ рдорд┐рд▓реЗрдВрдЧреЗ:
private List<Method> getPublicMethods(final Class clazz) { return Arrays.stream(clazz.getDeclaredMethods()) .filter(METHOD_FILTER) .collect(toList()); }
рдЬрд╣рд╛рдВ METHOD_FILTER рдПрдХ рдирд┐рдпрдорд┐рдд рд╡рд┐рдзреЗрдп рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐:
- рд╡рд┐рдзрд┐ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП
- рдпрд╣ рд╕рд┐рдВрдЯреИрдЯрд┐рдХ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдФрд░ рдРрд╕рд╛ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдХрдЪреНрдЪрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрддрд╛ рд╣реИ)
- рдпрд╣ рдЕрдореВрд░реНрдд рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдЕрд▓рдЧ-рдЕрд▓рдЧ рдФрд░ рдиреАрдЪреЗ рдХреЗ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ)
- рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрджрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рджреБрд╖реНрдЯ рд╡реНрдпрдХреНрддрд┐ рд╣рдорд╛рд░реЗ POJO рдврд╛рдВрдЪреЗ рдХреЗ рдЗрдирдкреБрдЯ рдкрд░ рдПрдХ рд╡рд░реНрдЧ рдХреЛ рдмрд░рд╛рдмрд░реА рдХреЗ рд╕рд╛рде рддрдп рдХрд░рддрд╛ рд╣реИ)
рд╣рдореЗрдВ рдЕрдкрдиреА рдЬрд░реВрд░рдд рдХреЗ рд╕рднреА рддрд░реАрдХреЗ рдорд┐рд▓ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЙрдиреНрд╣реЗрдВ рдПрдХ рд▓реВрдк рдореЗрдВ рдЫрд╛рдВрдЯрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ,
рдпрджрд┐ рд╡рд┐рдзрд┐ рдореЗрдВ рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рд╣рдорд╛рд░рд╛ рдЙрдореНрдореАрджрд╡рд╛рд░ рдирд╣реАрдВ рд╣реИ:
if (method.getParameterCount() == 0) { continue; }
рдпрджрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡реЗ @ рдиреЛрдЯреЛрдиреНрдпреВрд▓реЗрдЯреЗрдб рд╣реИрдВ (рдФрд░ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдХреНрдпрд╛ рдЙрдирдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП,
рддрд░реНрдХ- рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рдзрд┐
- рди @ рди
- рдЖрджрд┐рдо рдирд╣реАрдВ
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирдХреНрд╢рд╛ рдмрдирд╛рдПрдВ рдФрд░ рд╡рд┐рдзрд┐ рдореЗрдВ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣рдорд╛рд░реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЙрд╕рдореЗрдВ рдбрд╛рд▓ рджреЗрдВ, рдФрд░ рдЙрдирдХреЗ рд╡рд┐рдкрд░реАрдд рд╣рдо рдПрдХ рдЭрдВрдбрд╛ рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдЬреЛ рдХрд╣рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЯрд┐рдкреНрдкрдгреА @NonNull рдКрдкрд░ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдпрд╛ рдирд╣реАрдВ:
int nonNullAnnotationCount = 0; int index = 0; val parameterCurrentMethodArray = method.getParameters(); val notNullAnnotationParameterMap = new HashMap<Integer, Boolean>(); for (val parameter : parameterCurrentMethodArray) { if (isNull(parameter.getAnnotation(Nullable.class)) && isFalse(parameter.getType().isPrimitive())) { notNullAnnotationParameterMap.put(index++, true); nonNullAnnotationCount++; } else { notNullAnnotationParameterMap.put(index++, false); } } if (nonNullAnnotationCount == 0) { continue; }
рдпрд╣ рдирдХреНрд╢рд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИ, рдлрд┐рд░ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдПрдиреЛрдЯреЗрд╢рди @ рдиреЛрдирд▓ рдХреЗ рд╕рд╛рде рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрд╛рд░реА-рдмрд╛рд░реА рд╕реЗ рдкрд╛рд╕ рдХрд░реЗрдВ, рдФрд░ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдПрдХ рдХреЛ рдирд╣реАрдВред
NonNullAnnotationCount рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рдзрд┐ рдореЗрдВ рдХрд┐рддрдиреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ @NonNull рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдПрдХреАрдХрд░рдг рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ред
рд╡реИрд╕реЗ, рдЕрдЧрд░ рдХреЛрдИ @ рдиреЛрдирд▓ рдПрдиреЛрдЯреЗрд╢рди рдирд╣реАрдВ рд╣реИрдВ (рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рднреА рдЖрджрд┐рдо рдпрд╛ @ рдиреЙрдмрд▓ рд╣реИрдВ), рддреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ:
if (nonNullAnnotationCount == 0) { continue; }
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдПрдХ рдирдХреНрд╢рд╛ рд╣реИред рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдиреА рдмрд╛рд░ рдФрд░ рдХрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЕрд╢рдХреНрдд рдХрд░рдирд╛ рд╣реИ, рдорд╛рдорд▓рд╛ рдЫреЛрдЯрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рднреЛрд▓реЗрдкрди рд╕реЗ рдмрд┐рдирд╛ рд╕рдордЭреЗ рд╕реЛрдЪрд╛ рд╣реИ), рд╣рдореЗрдВ рдХрдХреНрд╖рд╛ рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдмрдирд╛рдиреЗ рдФрд░ рдЙрди рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдорд╕реНрдпрд╛рдПрдВ рддрдм рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВ рдЬрдм рдЖрдкрдХреЛ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЙрджрд╛рд╣рд░рдг рдХрд┐рддрдирд╛ рдЕрд▓рдЧ рд╣реИ: рдпрд╣ рдПрдХ рдирд┐рдЬреА рд╡рд░реНрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдкреИрд░рд╛рдореАрдЯрд░, рдРрд╕реЗ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд╕рд╛рде, рдПрдХ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ, рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рдЗрд╕рдХреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде), рдЬреЛ рднреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реИрдВ рдФрд░ рдЬрд┐рд╕реЗ рднреА рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ)ред
рдФрд░ рдЬрдм рд╣рдордиреЗ рд╣реБрдХ рджреНрд╡рд╛рд░рд╛ рдпрд╛ рдмрджрдорд╛рд╢ рджреНрд╡рд╛рд░рд╛ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛, рддреЛ рд╣рдореЗрдВ рдЗрдирд╡реЛрдХ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рднреА рд╡рд┐рд╕реНрддрд╛рд░: рдЕрдВрддрд┐рдо рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП? рдФрд░ рдПрдирдо? рдФрд░ рдЖрджрд┐рдо? рдФрд░ рдЖрджрд┐рдореЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА (рдЬреЛ рдПрдХ рд╡рд╕реНрддреБ рднреА рд╣реИ рдФрд░ рдПрдиреЛрдЯреЗрдЯ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИ)ред
рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдЗрд╕реЗ рдХреНрд░рдо рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВред
рдкрд╣рд▓рд╛ рдорд╛рдорд▓рд╛ рдПрдХ рдирд┐рдЬреА рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рд╣реИ:
if (ONLY_ONE_PRIVATE_CONSTRUCTOR_FILTER.test(clazz)) { notNullAnnotationParameterMap.put(currentNullableIndex, false); method.invoke(clazz, invokeMethodParameterArray); makeErrorMessage(method); }
рддрдм рд╣рдо рдмрд╕ рдЕрдкрдиреА рдЗрдирд╡реЛрдХ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЙрд╕ рдХреНрд▓реЛрдЬрд╝ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдмрд╛рд╣рд░ рд╕реЗ рдЖрдпрд╛ рд╣реИ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди @ рдиреЛрдирд▓ рдХреЗ рд▓рд┐рдП рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╕реНрдерд╛рди рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд╛рд░реНрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрд╛рдж рд░рдЦреЗрдВ, рдКрдкрд░ рд╣рдордиреЗ рдореИрдк @ рдиреЙрди-рдиреЗрд▓реНрд╕ рдмрдирд╛рдП) рд▓реВрдк рдореЗрдВ рдЪрд▓рд╛рдПрдВ рдФрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рдПрдВ, рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдирд▓ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓ рджреЗрдВ, рдФрд░ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдзреНрд╡рдЬ рдХреЛ рд╢реВрдиреНрдп рдХрд░реЗрдВ, рддрд╛рдХрд┐ рдЕрдЧрд▓реЗ рдПрдХреАрдХрд░рдг рдореЗрдВ рдЕрдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рд╢реВрдиреНрдп рд╣реЛ рдЬрд╛рдПред
рдХреЛрдб рдореЗрдВ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
val invokeMethodParameterArray = new Object[parameterCurrentMethodArray.length]; boolean hasNullParameter = false; int currentNullableIndex = 0; for (int i = 0; i < invokeMethodParameterArray.length; i++) { if (notNullAnnotationParameterMap.get(i) && isFalse(hasNullParameter)) { currentNullableIndex = i; invokeMethodParameterArray[i] = null; hasNullParameter = true; } else { mappingParameter(parameterCurrentMethodArray[i], invokeMethodParameterArray, i); } }
рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рдХрд╛ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЗрдВрдЯрд░рдлреЗрд╕, рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓реЗрдирд╛ рдФрд░ рдмрдирд╛рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ (рдЗрд╕рдореЗрдВ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рднреА рдирд╣реАрдВ рд╣реИ)ред
рдЗрд╕рд▓рд┐рдП, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:
if (INTERFACE_FILTER.test(clazz)) { notNullAnnotationParameterMap.put(currentNullableIndex, false); method.invoke(createInstanceByDynamicProxy(clazz, invokeMethodParameterArray), invokeMethodParameterArray); makeErrorMessage(method); }
createInstanceByDynamicProxy рд╣рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдпрджрд┐ рдпрд╣ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рд╕реНрд╡рдпрдВ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ
рдЕрддрд┐ рд╕реВрдХреНрд╖реНрдо рдЕрдВрддрд░рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдпрд╣рд╛рдВ рдпрд╣ рдореМрд▓рд┐рдХ рд░реВрдк рд╕реЗ рд╣реИ рдЬреЛ рдХрдХреНрд╖рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдкреНрд░рдХрд╛рд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рдФрд░ рдХреБрдЫ рддреБрд▓рдирд╛ рдирд╣реАрдВ) рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдРрд╕реЗ рддрд░реАрдХреЗ рд╣реИрдВ рдЬреЛ рдЖрдк рд▓рдХреНрд╖реНрдп рд╡рд░реНрдЧ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛ рдЙрджрд╛рд╣рд░рдг рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░реЗрдЧрд╛
рд▓реЗрдХрд┐рди рдЕрдВрджрд░ рдРрд╕рд╛ рд╣реИ:
private Object createInstanceByDynamicProxy(final Class clazz, final Object[] invokeMethodParameterArray) { return newProxyInstance( currentThread().getContextClassLoader(), new Class[]{clazz}, (proxy, method1, args) -> { Constructor<Lookup> constructor = Lookup.class .getDeclaredConstructor(Class.class); constructor.setAccessible(true); constructor.newInstance(clazz) .in(clazz) .unreflectSpecial(method1, clazz) .bindTo(proxy) .invokeWithArguments(invokeMethodParameterArray); return null; } ); }
рдЬреЗрд▓реАрд╡реИрд╕реЗ, рдпрд╣рд╛рдВ рдХреБрдЫ рд░реЗрдХ рднреА рдереЗ, рдореБрдЭреЗ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдм рдХреМрди рд╕реЗ рд╣реИрдВ, рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рд╕реЗ рдереЗ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рд▓реБрдХрдЕрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдкреНрд░реЙрдХреНрд╕реА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЕрдЧрд▓рд╛ рдЙрджрд╛рд╣рд░рдг (рдореЗрд░рд╛ рдкрд╕рдВрджреАрджрд╛) рдПрдХ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╣реИред рдФрд░ рдпрд╣рд╛рдВ рдбрд╛рдпрдиреЗрдорд┐рдХ рдкреНрд░реЙрдХреНрд╕реА рдЕрдм рд╣рдорд╛рд░реА рдорджрдж рдирд╣реАрдВ рдХрд░реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рдХреЛрдИ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рдХрд┐рд╕реА рддрд░рд╣ рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╣ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ рдЬреИрд╕рд╛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдФрд░ рдРрд╕реЗ рд╣реА, рд╣рдо рдПрдХ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рд╕реЗ newInstance () рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рд╕реАрдЬреАрдПрд▓рдЖрдИрдмреА рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрдПрдЧрд╛, рдПрдХ рд╡рд╕рдВрдд рджреЗрдпрддрд╛ рдЬреЛ рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкрд░рджреЗ рдХреЗ рдкреАрдЫреЗ рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реЗрд╢рд╛рдиреА рдпрд╣ рд╣реИ рдХрд┐, рд▓рдХреНрд╖реНрдп рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ (рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛) рдирд┐рд░реНрдорд╛рддрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рдЧрдкрд╢рдкрд╣рд╛рд▓рд╛рдВрдХрд┐ рд╕реНрдкреНрд░рд┐рдВрдЧ 4 рдХреЗ рдмрд╛рдж рд╕реЗ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЧрдкрд╢рдк рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, CGLIB рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП: рддреЛ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ!
рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ рдХреЛ рддрддреНрдХрд╛рд▓ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдпрд╣ рд╣реЛрдЧрд╛:
if (isAbstract(clazz.getModifiers())) { createInstanceByCGLIB(clazz, method, invokeMethodParameterArray); makeErrorMessage(); }
makeErrorMessage (), рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рджреЗрдЦрд╛ рдЧрдпрд╛ рдерд╛, рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдЕрдЧрд░ рд╣рдордиреЗ рдПрдиреЛрдЯреЗрдЯ @ рдПрдирдСрдирд▓рд╛рдЗрди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХреЛ рдЕрд╢рдХреНрдд рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдирд╣реАрдВ рдЧрд┐рд░рддрд╛ рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдбреНрд░реЙрдк рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдкреИрд░рд╛рдореАрдЯрд░ рдореИрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХрд╛ рд╣реИ рдЬреЛ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдФрд░ рд╡рд┐рдзрд┐ рджреЛрдиреЛрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдореИрдк рдФрд░ рд▓реЙрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
private void mappingParameter(final Parameter parameter, final Object[] methodParam, final int index) throws InstantiationException, IllegalAccessException { if (isFinal(parameter.getType().getModifiers())) { if (parameter.getType().isEnum()) { methodParam[index] = Enum.valueOf( (Class<Enum>) (parameter.getType()), parameter.getType().getEnumConstants()[0].toString() ); } else if (parameter.getType().isPrimitive()) { mappingPrimitiveName(parameter, methodParam, index); } else if (parameter.getType().getTypeName().equals("byte[]")) { methodParam[index] = new byte[0]; } else { methodParam[index] = parameter.getType().newInstance(); } } else { methodParam[index] = mock(parameter.getType()); } }
Enum (рдХреЗрдХ рдкрд░ рдЪреЗрд░реА) рдХреЗ рдирд┐рд░реНрдорд╛рдг рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЖрдк Enum рдХреЛ рдХреЗрд╡рд▓ рд▓реЗ рдФрд░ рдмрдирд╛ рдирд╣реАрдВ рд╕рдХрддреЗред
рдпрд╣рд╛рдБ рдЕрдВрддрд┐рдо рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░рдг, рдЧреИрд░-рдЕрдВрддрд┐рдо рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ, рдФрд░ рдлрд┐рд░ рдмрд╕ рдкрд╛рда (рдХреЛрдб) рдореЗрдВред
рдЦреИрд░, рд╣рдордиреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рд▓рд┐рдП рдФрд░ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдкрдирд╛ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ:
val firstFindConstructor = clazz.getConstructors()[0]; val constructorParameterArray = new Object[firstFindConstructor.getParameters().length]; for (int i = 0; i < constructorParameterArray.length; i++) { mappingParameter(firstFindConstructor.getParameters()[i], constructorParameterArray, i); } notNullAnnotationParameterMap.put(currentNullableIndex, false); createAndInvoke(clazz, method, invokeMethodParameterArray, firstFindConstructor, constructorParameterArray); makeErrorMessage(method);
рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ рдХрд┐ рдЪреВрдВрдХрд┐ рд╣рдо рдХреЛрдб рдХреЗ рдЗрд╕ рдЪрд░рдг рдореЗрдВ рдкрд╣реБрдВрдЪ рдЪреБрдХреЗ рд╣реИрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдирд┐рд░реНрдорд╛рддрд╛ рд╣реИ, рд╣рдо рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рднреА рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдкрд╣рд▓реЗ рдПрдХ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ, рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреЙрд▓ рдХрд░реЗрдВ рдЗрд╕ рддрд░рд╣:
method.invoke(spy(clazz.getConstructors()[0].newInstance()), invokeMethodParameterArray);
рдЦреИрд░, рдЕрдЧрд░ рдРрд╕рд╛ рдХреБрдЫ рд╣реИ:
method.invoke(spy(clazz.getConstructors()[0].newInstance()), invokeMethodParameterArray);
рдпрд╣ рд╡рд╣ рддрд░реНрдХ рд╣реИ рдЬреЛ createAndInvoke () рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдиреЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рджреЗрдЦрд╛ рдерд╛ред
рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд рдкрд░реАрдХреНрд╖рдг рд╡рд░реНрдЧ рдХрд╛ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг, рдореИрдВрдиреЗ рдЧрд┐рдЯ рдкрд░ рдЕрдкрд▓реЛрдб рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдПрдХ рдХрд╛рд░реНрдпрд╢реАрд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рд▓рд┐рдЦрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдФрд░ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕реНрд░реЛрдд рдХреЛрдб public class TestUtil { private static final Predicate<Method> METHOD_FILTER = method -> isPublic(method.getModifiers()) && isFalse(method.isSynthetic()) && isFalse(isAbstract(method.getModifiers())) && isFalse(method.getName().equals("equals")); private static final Predicate<Class> ONLY_ONE_PRIVATE_CONSTRUCTOR_FILTER = clazz -> clazz.getConstructors().length == 0 && isFalse(clazz.isInterface()); private static final Predicate<Class> INTERFACE_FILTER = clazz -> clazz.getConstructors().length == 0; private static final BiPredicate<Exception, Parameter> LOMBOK_ERROR_FILTER = (exception, parameter) -> isNull(exception.getCause().getMessage()) || isFalse(exception.getCause().getMessage().equals(parameter.getName())); protected void assertNonNullAnnotation(final Class clazz) throws Throwable { for (val method : getPublicMethods(clazz)) { if (method.getParameterCount() == 0) { continue; } int nonNullAnnotationCount = 0; int index = 0; val parameterCurrentMethodArray = method.getParameters(); val notNullAnnotationParameterMap = new HashMap<Integer, Boolean>(); for (val parameter : parameterCurrentMethodArray) { if (isNull(parameter.getAnnotation(Nullable.class)) && isFalse(parameter.getType().isPrimitive())) { notNullAnnotationParameterMap.put(index++, true); nonNullAnnotationCount++; } else { notNullAnnotationParameterMap.put(index++, false); } } if (nonNullAnnotationCount == 0) { continue; } for (int j = 0; j < nonNullAnnotationCount; j++) { val invokeMethodParameterArray = new Object[parameterCurrentMethodArray.length]; boolean hasNullParameter = false; int currentNullableIndex = 0; for (int i = 0; i < invokeMethodParameterArray.length; i++) { if (notNullAnnotationParameterMap.get(i) && isFalse(hasNullParameter)) { currentNullableIndex = i; invokeMethodParameterArray[i] = null; hasNullParameter = true; } else { mappingParameter(parameterCurrentMethodArray[i], invokeMethodParameterArray, i); } } try { if (ONLY_ONE_PRIVATE_CONSTRUCTOR_FILTER.test(clazz)) { notNullAnnotationParameterMap.put(currentNullableIndex, false); method.invoke(clazz, invokeMethodParameterArray); makeErrorMessage(method); } if (INTERFACE_FILTER.test(clazz)) { notNullAnnotationParameterMap.put(currentNullableIndex, false); method.invoke(createInstanceByDynamicProxy(clazz, invokeMethodParameterArray), invokeMethodParameterArray); makeErrorMessage(method); } if (isAbstract(clazz.getModifiers())) { createInstanceByCGLIB(clazz, method, invokeMethodParameterArray); makeErrorMessage(); } val firstFindConstructor = clazz.getConstructors()[0]; val constructorParameterArray = new Object[firstFindConstructor.getParameters().length]; for (int i = 0; i < constructorParameterArray.length; i++) { mappingParameter(firstFindConstructor.getParameters()[i], constructorParameterArray, i); } notNullAnnotationParameterMap.put(currentNullableIndex, false); createAndInvoke(clazz, method, invokeMethodParameterArray, firstFindConstructor, constructorParameterArray); makeErrorMessage(method); } catch (final Exception e) { if (LOMBOK_ERROR_FILTER.test(e, parameterCurrentMethodArray[currentNullableIndex])) { makeErrorMessage(method); } } } } } @SneakyThrows private void createAndInvoke( final Class clazz, final Method method, final Object[] invokeMethodParameterArray, final Constructor firstFindConstructor, final Object[] constructorParameterArray ) { if (firstFindConstructor.getParameters().length == 0) { method.invoke(spy(clazz.getConstructors()[0].newInstance()), invokeMethodParameterArray); } else { method.invoke(spy(clazz.getConstructors()[0].newInstance(constructorParameterArray)), invokeMethodParameterArray); } } @SneakyThrows private void createInstanceByCGLIB(final Class clazz, final Method method, final Object[] invokeMethodParameterArray) { MethodInterceptor handler = (obj, method1, args, proxy) -> proxy.invoke(clazz, args); if (clazz.getConstructors().length > 0) { val firstFindConstructor = clazz.getConstructors()[0]; val constructorParam = new Object[firstFindConstructor.getParameters().length]; for (int i = 0; i < constructorParam.length; i++) { mappingParameter(firstFindConstructor.getParameters()[i], constructorParam, i); } for (val constructor : clazz.getConstructors()) { if (constructor.getParameters().length == 0) { val proxy = Enhancer.create(clazz, handler); method.invoke(proxy.getClass().newInstance(), invokeMethodParameterArray); } } } } private Object createInstanceByDynamicProxy(final Class clazz, final Object[] invokeMethodParameterArray) { return newProxyInstance( currentThread().getContextClassLoader(), new Class[]{clazz}, (proxy, method1, args) -> { Constructor<Lookup> constructor = Lookup.class .getDeclaredConstructor(Class.class); constructor.setAccessible(true); constructor.newInstance(clazz) .in(clazz) .unreflectSpecial(method1, clazz) .bindTo(proxy) .invokeWithArguments(invokeMethodParameterArray); return null; } ); } private void makeErrorMessage() { fail(" @NonNull DefaultConstructor "); } private void makeErrorMessage(final Method method) { fail(" " + method.getName() + " @NonNull"); } private List<Method> getPublicMethods(final Class clazz) { return Arrays.stream(clazz.getDeclaredMethods()) .filter(METHOD_FILTER) .collect(toList()); } private void mappingParameter(final Parameter parameter, final Object[] methodParam, final int index) throws InstantiationException, IllegalAccessException { if (isFinal(parameter.getType().getModifiers())) { if (parameter.getType().isEnum()) { methodParam[index] = Enum.valueOf( (Class<Enum>) (parameter.getType()), parameter.getType().getEnumConstants()[0].toString() ); } else if (parameter.getType().isPrimitive()) { mappingPrimitiveName(parameter, methodParam, index); } else if (parameter.getType().getTypeName().equals("byte[]")) { methodParam[index] = new byte[0]; } else { methodParam[index] = parameter.getType().newInstance(); } } else { methodParam[index] = mock(parameter.getType()); } } private void mappingPrimitiveName(final Parameter parameter, final Object[] methodParam, final int index) { val name = parameter.getType().getName(); if ("long".equals(name)) { methodParam[index] = 0L; } else if ("int".equals(name)) { methodParam[index] = 0; } else if ("byte".equals(name)) { methodParam[index] = (byte) 0; } else if ("short".equals(name)) { methodParam[index] = (short) 0; } else if ("double".equals(name)) { methodParam[index] = 0.0d; } else if ("float".equals(name)) { methodParam[index] = 0.0f; } else if ("boolean".equals(name)) { methodParam[index] = false; } else if ("char".equals(name)) { methodParam[index] = 'A'; } } }
рдирд┐рд╖реНрдХрд░реНрд╖
рдпрд╣ рдХреЛрдб рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд▓рд╣рд╛рд▓ рдПрдХ рд╣реА рд╡рд┐рдХрд▓реНрдк рд╕рдВрднрд╡ рд╣реИ, рдЬрдм рд╕рдм рдХреБрдЫ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдХ рд▓реЛрдореНрдмреЙрдХ рд╕реЗрдЯрд░ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ (рдпрджрд┐ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╣реИ рдЬреЛ рд╕реЗрдЬрд╝реЛ рдХреНрд▓рд╛рд╕ рдореЗрдВ рд╕реЗрдЯрд░ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ) рдФрд░ рдЬрд┐рд╕ рдХреНрд╖реЗрддреНрд░ рдкрд░ рд╕реЗрдЯрд░ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рд╡рд╣ рдЕрдВрддрд┐рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
рдлрд┐рд░ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреГрдкрдпрд╛ рдпрд╣ рдХрд╣реЗрдЧрд╛ рдХрд┐ рдПрдХ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рдХреЛрдИ @NonNull рдПрдиреЛрдЯреЗрд╢рди рдирд╣реАрдВ рд╣реИ, рд╕рдорд╛рдзрд╛рди рд╕рд░рд▓ рд╣реИ: рд▓реЙрдЯрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрдкрдиреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рдПрдиреЛрдЯрдирд▓ / @ Nullable рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрдкрдиреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдиреЛрдЯреЗрдЯ рдХрд░реЗрдВред
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ (рдпрд╛ рдХреБрдЫ рдФрд░) рдореЗрдВ рд╡рд┐рдзрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдирд╛рдо рд╕реЗ рдмрдВрдзрд╛ рд░рд╣реВрдВ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдЪрд░ рдирд╛рдо рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ, рдЖрдк arg [0] рдФрд░ arg [1], рдЖрджрд┐ рдкрд╛рдПрдВрдЧреЗред ред
рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рд╡рд┐рдзрд┐ рдирд╛рдореЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдорд╛рд╡реЗрди рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>${compile.target.source}</source/> <target>${compile.target.source}</target> <encoding>${project.build.sourceEncoding}</encoding> <compilerArgs><arg>-parameters</arg></compilerArgs> </configuration> </plugin>
рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕ рдХреБрдВрдЬреА:
<compilerArgs><arg>-parameters</arg></compilerArgs>
рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рдереЗред