рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рдореИрдВ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ
рдХреБрдЦреНрдпрд╛рдд рдЬреЗрдХ рд╡реЛрд░реНрдЯрди рджреНрд╡рд╛рд░рд╛ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реЗ рдПрдХ рдЕрджреНрднреБрдд рд▓реЗрдЦ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдХреИрд╕реЗ рдЬрд╛рд╡рд╛ рд╕реЗ рдПрдВрдбреНрд░реЙрдЗрдб 8 рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдореВрд▓ рд▓реЗрдЦ рдпрд╣рд╛рдБ рд╣реИрдореИрдВрдиреЗ рдХрдИ рд╡рд░реНрд╖реЛрдВ рддрдХ рдШрд░ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛, рдФрд░ рдореИрдВрдиреЗ рдЕрдХреНрд╕рд░ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЛ рдЬрд╛рд╡рд╛ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╢рд┐рдХрд╛рдпрдд рдХрд░рддреЗ рд╕реБрдирд╛ред
рдпрд╣ рдПрдХ рдЬрдЯрд┐рд▓ рд╡рд┐рд╖рдп рд╣реИред рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ "рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдЬрд╛рд╡рд╛ рд╕рдкреЛрд░реНрдЯ" рд╕реЗ рд╣рдорд╛рд░рд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рднрд╛рд╖рд╛ рдХреЗ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдЪреАрдЬреЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ: рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд▓реИрдореНрдмреНрдбрд╛), рдмрд╛рдЗрдЯрдХреЛрдб, рдЯреВрд▓реНрд╕, рдПрдкреАрдЖрдИ, рдЬреЗрд╡реАрдПрдо рдФрд░ рдЗрд╕реА рддрд░рд╣ред
рдЬрдм рд▓реЛрдЧ рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдЬрд╛рд╡рд╛ 8 рд╕рдорд░реНрдерди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЙрдирдХрд╛ рдорддрд▓рдм рдЖрдорддреМрд░ рдкрд░ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реЛрддрд╛ рд╣реИред рддреЛ, рдЪрд▓реЛ рдЙрдирдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рд▓реИрдореНрдмреНрдбрд╛
рдЬрд╛рд╡рд╛ 8 рдХреЗ рдореБрдЦреНрдп рдирд╡рд╛рдЪрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд▓рдВрдмреЛрджрд░ рдерд╛ред
рдХреЛрдб рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдФрд░ рд╕рд░рд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд▓реИрдореНрдмреНрдбрд╛ рдиреЗ рд╣рдореЗрдВ рдПрдХ рдПрдХрд▓ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмреЛрдЭрд┐рд▓ рдЕрдирд╛рдо рдХрдХреНрд╖рд╛рдПрдВ рд▓рд┐рдЦрдиреЗ рд╕реЗ рдмрдЪрд╛рдпрд╛ рд╣реИред
class Java8 { interface Logger { void log(String s); } public static void main(String... args) { sayHi(s -> System.out.println(s)); } private static void sayHi(Logger logger) { logger.log("Hello!"); } }
Javac рдФрд░ legacy
dx tool
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ:
$ javac *.java $ ls Java8.java Java8.class Java8$Logger.class $ $ANDROID_HOME/build-tools/28.0.2/dx --dex --output . *.class Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in Java8.main:([Ljava/lang/String;)V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) 1 error; aborting
рдпрд╣ рддреНрд░реБрдЯрд┐ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реЛрддреА рд╣реИ рдХрд┐
invokedynamic
рдореЗрдВ рдПрдХ рдирдП рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ -
invokedynamic
, рдЬрд┐рд╕реЗ рдЬрд╛рд╡рд╛ 7 рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред рддреНрд░реБрдЯрд┐ рдкрд╛рда рд╕реЗ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗрд╡рд▓ 26 рдПрдкреАрдЖрдИ (рдПрдВрдбреНрд░реЙрдЗрдб 8) рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╢рд╛рдпрдж рд╣реА рдХреЛрдИ 26 minApi рдХреЗ рд╕рд╛рде рдХреЛрдИ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬрд╛рд░реА рдХрд░реЗрдЧрд╛ред рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рддрдерд╛рдХрдерд┐рдд
рдбрд┐рд╕реБрдЧрд░рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬреЛ рдПрдкреАрдЖрдИ рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рд▓реИрдореНрдмреНрдбрд╛ рд╕рдорд░реНрдерди рдХреЛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред
Desaccharization рдХрд╛ рдЗрддрд┐рд╣рд╛рд╕
рд╡рд╣ Android рджреБрдирд┐рдпрд╛ рдореЗрдВ рдмрд╣реБрдд рд░рдВрдЧреАрди рд╣реИред Desaccharization рдХрд╛ рд▓рдХреНрд╖реНрдп рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рд╣реИ - рд╕рднреА рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирдИ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдирд╛ред
рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ
рд░реЗрдЯреНрд░реЛрд▓рдВрдмрд╛ рдкреНрд▓рдЧрдЗрди рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд┐рдпрд╛ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдЬреЗрд╡реАрдПрдо рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рд▓реИрдореНрдмрджрд╛рд╕ рдХреЛ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрд╕реЗ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдХрд┐рдпрд╛, рдФрд░ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдирд╣реАрдВред рддрд░реАрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрддреНрдкрдиреНрди рдХрдХреНрд╖рд╛рдПрдВ рдмрд╣реБрдд рдорд╣рдВрдЧреА рдереАрдВ, рд▓реЗрдХрд┐рди рд╕рдордп рдХреЗ рд╕рд╛рде, рд╕реБрдзрд╛рд░реЛрдВ рдФрд░ рд╕реБрдзрд╛рд░реЛрдВ рдХреЗ рдмрд╛рдж, рдпрд╣ рд╕рдВрдХреЗрддрдХ рдХрдо рдпрд╛ рдЬреНрдпрд╛рджрд╛ рдЙрдЪрд┐рдд рдХреБрдЫ рдХрдо рд╣реЛ рдЧрдпрд╛ред
рдлрд┐рд░, рдПрдВрдбреНрд░реЙрдЗрдб рдЯреАрдо
рдиреЗ рдПрдХ рдирдП рд╕рдВрдХрд▓рдХ рдХреА рдШреЛрд╖рдгрд╛ рдХреА рдЬреЛ рд╕рднреА рдЬрд╛рд╡рд╛ 8 рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рдерд╛ред рдЗрд╕реЗ рдПрдХреНрд▓рд┐рдкреНрд╕ рдЬрд╛рд╡рд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рдКрдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЬрд╛рд╡рд╛ рдмрд╛рдЗрдЯрдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЗрд╕рдиреЗ рдПрдХ Dalvik рдмрд╛рдпрдЯреЗрдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЕрднреА рднреА рд╡рд╛рдВрдЫрд┐рдд рд╣реЛрдирд╛ рдмрд╛рдХреА рд╣реИред
рдЬрдм рдирдпрд╛ рд╕рдВрдХрд▓рдХ (рд╕реМрднрд╛рдЧреНрдп рд╕реЗ) рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЬрд╛рд╡рд╛ рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рдЬрд╛рд╡рд╛ рдмрд╛рдЗрдЯрдХреЛрдб рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдорд░, рдЬреЛ рдмрд╛рдЬреАрдЧрд░реА рдХрд░рддрд╛
рдерд╛ , Google рдХреЗ рдмрд┐рд▓реНрдб рд╕рд┐рд╕реНрдЯрдо,
рдмрдЬрд╝реЗрд▓ рд╕реЗ
рдПрдВрдбреНрд░реЙрдЗрдб рдЧреНрд░реИрдЧрд▓ рдкреНрд▓рдЧрд┐рди рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред рдФрд░ рдЗрд╕рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдЕрднреА рднреА рдХрдо рдерд╛, рдЗрд╕рд▓рд┐рдП рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдХреА рдЦреЛрдЬ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЬрд╛рд░реА рд░рд╣реАред
рдФрд░ рдЕрдм рд╣рдореЗрдВ
dexer
-
рдбреА 8 рдХреЗ dexer
рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕реЗ
dx tool
рдХреЛ рдмрджрд▓рдирд╛ рдерд╛ред Desaccharization рдЕрдм рд╕рдВрдХрд▓рд┐рдд JAR рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ
.dex
(рдбреЗрдХреНрд╕рд┐рдВрдЧ) рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рджреМрд░рд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред D8,
dx
рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ, рдФрд░ рдПрдВрдбреНрд░реЙрдЗрдб рдЧреНрд░реИрдбрд▓ рдкреНрд▓рдЧрд┐рди 3.1 рдХреЗ рдмрд╛рдж рд╕реЗ рдпрд╣ рдбрд┐рдлреЙрд▓реНрдЯ рдбрд┐рдХреНрд╕рд░ рдмрди рдЧрдпрд╛ рд╣реИред
D8
рдЕрдм, D8 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
$ java -jar d8.jar \ --lib $ANDROID_HOME/platforms/android-28/android.jar \ --release \ --output . \ *.class $ ls Java8.java Java8.class Java8$Logger.class classes.dex
рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдбреА 8 рдиреЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдХреИрд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛, рдЖрдк
dexdump tool
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдПрд╕рдбреАрдХреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрд╣ рдХрд╛рдлреА рдХреБрдЫ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рд╣рдо рдХреЗрд╡рд▓ рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ:
$ $ANDROID_HOME/build-tools/28.0.2/dexdump -d classes.dex [0002d8] Java8.main:([Ljava/lang/String;)V 0000: sget-object v0, LJava8$1;.INSTANCE:LJava8$1; 0002: invoke-static {v0}, LJava8;.sayHi:(LJava8$Logger;)V 0005: return-void [0002a8] Java8.sayHi:(LJava8$Logger;)V 0000: const-string v0, "Hello" 0002: invoke-interface {v1, v0}, LJava8$Logger;.log:(Ljava/lang/String;)V 0005: return-void тАж
рдпрджрд┐ рдЖрдк рдЕрднреА рддрдХ рдмрд╛рдИрдЯрдХреЛрдб рдирд╣реАрдВ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВ: рдпрд╣рд╛рдБ рдЬреЛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрд╕рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛ рд╕рд╣рдЬ рд░реВрдк рд╕реЗ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкрд╣рд▓реЗ рдмреНрд▓реЙрдХ рдореЗрдВ, рдЗрдВрдбреЗрдХреНрд╕
0000
рд╕рд╛рде рд╣рдорд╛рд░реА
main
рд╡рд┐рдзрд┐ рдХреЛ
INSTANCE
рдлрд╝реАрд▓реНрдб рд╕реЗ
INSTANCE
рдХреНрд▓рд╛рд╕
Java8$1
рд╕рдВрджрд░реНрдн рдорд┐рд▓рддрд╛ рд╣реИред рдпрд╣ рд╡рд░реНрдЧ
рджреМрд░рд╛рди рдЙрддреНрдкрдиреНрди рд╣реБрдЖ рдерд╛ред рдореБрдЦреНрдп рд╡рд┐рдзрд┐ рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд╢рд░реАрд░ рдХрд╛ рдХреЛрдИ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдпрд╣
Java8$1
рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред рдЗрдВрдбреЗрдХреНрд╕
0002
рддрдм
sayHi
рдХреЗ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
sayHi
рд╕реНрдЯреЗрдЯрд┐рдХ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
sayHi
рд▓рд┐рдП
Java8$Logger
рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐
Java8$1
рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдпрд╣рд╛рдВ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
Class #2 - Class descriptor : 'LJava8$1;' Access flags : 0x1011 (PUBLIC FINAL SYNTHETIC) Superclass : 'Ljava/lang/Object;' Interfaces - #0 : 'LJava8$Logger;'
SYNTHETIC
рдзреНрд╡рдЬ рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐
Java8$1
рд╡рд░реНрдЧ рдЙрддреНрдкрдиреНрди
Java8$1
рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреА рд╕реВрдЪреА рдореЗрдВ
Java8$Logger
ред
рдпрд╣ рд╡рд░реНрдЧ рд╣рдорд╛рд░реЗ рд▓рдВрдмреЛрджрд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк
log
рд╡рд┐рдзрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд▓реИрдореНрдмрдбрд╛ рдХреЗ рд╢рд░реАрд░ рдХреЛ рдирд╣реАрдВ рджреЗрдЦреЗрдВрдЧреЗред
тАж [00026c] Java8$1.log:(Ljava/lang/String;)V 0000: invoke-static {v1}, LJava8;.lambda$main$0:(Ljava/lang/String;)V 0003: return-void тАж
рдЗрд╕рдХреЗ рдмрдЬрд╛рдп,
Java8
рд╡рд░реНрдЧ рдХреА
static
рд╡рд┐рдзрд┐ рдХреЛ
Java8
-
Java8
lambda$main$0
ред рдореИрдВ рджреЛрд╣рд░рд╛рддрд╛ рд╣реВрдВ, рдпрд╣ рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХреА рдЬрд╛рддреА рд╣реИред
тАж #1 : (in LJava8;) name : 'lambda$main$0' type : '(Ljava/lang/String;)V' access : 0x1008 (STATIC SYNTHETIC) [0002a0] Java8.lambda$main$0:(Ljava/lang/String;)V 0000: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; 0002: invoke-virtual {v0, v1}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V 0005: return-void
SYNTHETIC
рдзреНрд╡рдЬ рдлрд┐рд░ рд╕реЗ рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдзрд┐ рдЙрддреНрдкрдиреНрди рдХреА рдЧрдИ рдереА, рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рдХреЗрд╡рд▓ рд▓реИрдореНрдмрдбрд╛ рдмреЙрдбреА рд╢рд╛рдорд┐рд▓ рд╣реИ:
System.out.println
рд▓рд┐рдП рдПрдХ рдХреЙрд▓ред рд▓реИрдореНрдмреНрдбрд╛ рдмреЙрдбреА
Java8.class рдХреЗ рдЕрдВрджрд░ рд╣реЛрдиреЗ рдХрд╛ рдХрд╛рд░рдг рд╕рд░рд▓ рд╣реИ - рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХреЗ
private
рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬрд┐рд╕реЗ рдЙрддреНрдкрдиреНрди рд╡рд░реНрдЧ рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реЛрдЧреАред
рд╕рдм рдХреБрдЫ рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ
desaccharization рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕реЗ Dalvik bytecode рдореЗрдВ рджреЗрдЦрддреЗ рд╣реБрдП, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдФрд░ рднрдпрд╛рд╡рд╣ рд╣реИред
рд╕реНрд░реЛрдд рдкрд░рд┐рд╡рд░реНрддрди
рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐
desaccharization рдХреИрд╕реЗ рд╣реЛрддрд╛ рд╣реИ, рдЖрдЗрдП рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдХреЛ рдХреБрдЫ рдРрд╕реА рдЪреАрдЬреЛрдВ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрджрдо рд╕реЗ рдХрджрдо рдорд┐рд▓рд╛рдХрд░ рджреЗрдЦреЗрдВ рдЬреЛ рдПрдкреАрдЖрдИ рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░реЗрдВрдЧреАред
рдЪрд▓реЛ рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рд╡рд░реНрдЧ рд▓реЗрддреЗ рд╣реИрдВ:
class Java8 { interface Logger { void log(String s); } public static void main(String... args) { sayHi(s -> System.out.println(s)); } private static void sayHi(Logger logger) { logger.log("Hello!"); } }
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд▓реИрдореНрдмреНрдбрд╛ рдмреЙрдбреА рдХреЛ
package private
рдореЗрдердб рдореЗрдВ рд▓реЗ рдЬрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
public static void main(String... args) { - sayHi(s -> System.out.println(s)); + sayHi(s -> lambda$main$0(s)); } + + static void lambda$main$0(String s) { + System.out.println(s); + }
рдлрд┐рд░ рдПрдХ рд╡рд░реНрдЧ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ
Logger
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ рд▓реИрдореНрдмреНрдбрд╛ рдмреЙрдбреА рд╕реЗ рдХреЛрдб рдХрд╛ рдПрдХ рдмреНрд▓реЙрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИред
public static void main(String... args) { - sayHi(s -> lambda$main$0(s)); + sayHi(new Java8$1()); } @@ } + +class Java8$1 implements Java8.Logger { + @Override public void log(String s) { + Java8.lambda$main$0(s); + } +}
рдЗрд╕рдХреЗ рдмрд╛рдж,
Java8$1
рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдЗрдВрд╕реНрдЯреЗрдВрд╕
Java8$1
, рдЬрд┐рд╕реЗ
static
рд╡реЗрд░рд┐рдПрдмрд▓
INSTANCE
рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
public static void main(String... args) { - sayHi(new Java8$1()); + sayHi(Java8$1.INSTANCE); } @@ class Java8$1 implements Java8.Logger { + static final Java8$1 INSTANCE = new Java8$1(); + @Override public void log(String s) {
рдпрд╣рд╛рдВ рдЕрдВрддрд┐рдо
рдбрдм рдХреА рдЧрдИ рдХрдХреНрд╖рд╛ рд╣реИ
рдЬрд┐рд╕реЗ рдПрдкреАрдЖрдИ рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
class Java8 { interface Logger { void log(String s); } public static void main(String... args) { sayHi(Java8$1.INSTANCE); } static void lambda$main$0(String s) { System.out.println(s); } private static void sayHi(Logger logger) { logger.log("Hello!"); } } class Java8$1 implements Java8.Logger { static final Java8$1 INSTANCE = new Java8$1(); @Override public void log(String s) { Java8.lambda$main$0(s); } }
рдпрджрд┐ рдЖрдк Dalvik bytecode рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ Java8 $ 1 рдЬреИрд╕реЗ рдирд╛рдо рдирд╣реАрдВ рдорд┐рд▓реЗрдВрдЧреЗ - рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрдЧрд╛
-$$Lambda$Java8$QkyWJ8jlAksLjYziID4cZLvHwoY
ред рдХрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд╛рдордХрд░рдг рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдлрд╛рдпрджреЗ рдХреНрдпрд╛ рд╣реИрдВ, рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдореЗрдВ рдЖрддрд╛ рд╣реИред
рдореВрд▓ рдирд┐рд╡рд╛рд╕реА рдореЗрдордиреЗ рдХрд╛ рд╕рдорд░реНрдерди
рдЬрдм рд╣рдордиреЗ
dx tool
рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реИрдореНрдмрджрд╛рд╕ рд╕реЗ рдпреБрдХреНрдд рдХреНрд▓рд╛рд╕ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛, рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдиреЗ рдХрд╣рд╛ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ 26 APIs рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
$ $ANDROID_HOME/build-tools/28.0.2/dx --dex --output . *.class Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in Java8.main:([Ljava/lang/String;)V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) 1 error; aborting
рдЗрд╕рд▓рд┐рдП, рдпрд╣ рддрд░реНрдХрд╕рдВрдЧрдд рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╣рдо рдЗрд╕реЗ
тАФmin-api 26
рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ desaccharization рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
$ java -jar d8.jar \ --lib $ANDROID_HOME/platforms/android-28/android.jar \ --release \ --min-api 26 \ --output . \ *.class
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд░ рд╣рдо
.dex
рдлрд╝рд╛рдЗрд▓ рдХреЛ рдбрдВрдк рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЕрднреА рднреА рдЗрд╕рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
-$$Lambda$Java8$QkyWJ8jlAksLjYziID4cZLvHwoY
ред рдРрд╕рд╛ рдХреНрдпреЛрдВ? рдпрд╣ рдПрдХ рдбреА 8 рдмрдЧ рд╣реИ?
рдЗрд╕ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдпрд╣ рднреА рдХрд┐ рдбрд┐рд╕реНрдЪрд╛рд░реНрдЬрд╛рдЗрдЬреЗрд╢рди
рд╣рдореЗрд╢рд╛ рдХреНрдпреЛрдВ
рд╣реЛрддрд╛ рд╣реИ , рд╣рдореЗрдВ рдЬрд╛рд╡рд╛
Java8
рд╡рд░реНрдЧ рдХреЗ рдЬрд╛рд╡рд╛ рдмрд╛рдЗрдЯрдХреЛрдб рдХреЗ рдЕрдВрджрд░ рджреЗрдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред
$ javap -v Java8.class class Java8 { public static void main(java.lang.String...); Code: 0: invokedynamic
main
рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░, рд╣рдо рдлрд┐рд░ рд╕реЗ
0
рдЗрдВрдбреЗрдХреНрд╕ рдкрд░
рдЗрдиреНрд╡реЛрдХреЗрдиреНрдбреЗрдорд┐рдХ рджреЗрдЦрддреЗ рд╣реИрдВред рдХреЙрд▓ рдореЗрдВ рджреВрд╕рд░рд╛ рддрд░реНрдХ
0
- рдЗрд╕рд╕реЗ рдЬреБрдбрд╝реЗ
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рд╡рд┐рдзрд┐ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред
рдпрд╣рд╛рдВ
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреА рдЧрдИ рд╣реИ:
тАж BootstrapMethods: 0: #27 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:( Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType; Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite; Method arguments: #28 (Ljava/lang/String;)V #29 invokestatic Java8.lambda$main$0:(Ljava/lang/String;)V #28 (Ljava/lang/String;)V
рдпрд╣рд╛рдБ
рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рд╡рд┐рдзрд┐ рдХреЛ
java.lang.invoke.LambdaMetafactory
рд╡рд░реНрдЧ рдореЗрдВ
metafactory
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╣
рдЬреЗрдбреАрдХреЗ рдореЗрдВ рд░рд╣рддрд╛ рд╣реИ рдФрд░ рд▓рдВрдмреЛрджрд░ рдХреЗ рд▓рд┐рдП рд░рди-рдЯрд╛рдЗрдо рдореЗрдВ рдЧреБрдордирд╛рдо рдСрди-рдж-рдХреНрд▓рд╛рд╕ рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛рддрд╛ рд╣реИ, рдЙрд╕реА рддрд░рд╣ рдЬреИрд╕реЗ рдбреА 8 рдЙрдиреНрд╣реЗрдВ рдЧрдгрдирд╛ рд╕рдордп рдореЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк
Android java.lang.invoke
рдпрд╛
AOSP java.lang.invoke
рдХреЗ
AOSP java.lang.invoke
, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╡рд░реНрдЧ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдбреА-рдЬреБрдЧрд▓рд┐рдВрдЧ рд╣рдореЗрд╢рд╛ рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╣реИред VM
invokedynamic
рд╕рдорд╛рди
invokedynamic
рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди
invokedynamic
рдмрд┐рд▓реНрдЯ-рдЗрди JDK рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИред
рд╡рд┐рдзрд┐ рд╕рдВрджрд░реНрдн
рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд╕рд╛рде, рдЬрд╛рд╡рд╛ 8 рдиреЗ рд╡рд┐рдзрд┐ рд╕рдВрджрд░реНрдн рдЬреЛрдбрд╝рд╛ - рдпрд╣ рдПрдХ рд▓рдВрдмреЛрджрд╛ рдмрдирд╛рдиреЗ рдХрд╛ рдПрдХ рдкреНрд░рднрд╛рд╡реА рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╢рд░реАрд░ рдПрдХ рдореМрдЬреВрджрд╛ рдкрджреНрдзрддрд┐ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддрд╛ рд╣реИред
рд╣рдорд╛рд░рд╛
Logger
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдРрд╕рд╛ рд╣реА рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдореЗрдордиреЗ рдХреЗ рд╢рд░реАрд░ рдХреЛ
System.out.println
рд▓рд┐рдП рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдЗрдП рд▓реИрдореНрдмрдбрд╛ рдХреЛ рд╕рдВрджрд░реНрдн рд╡рд┐рдзрд┐ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ:
public static void main(String... args) { - sayHi(s -> System.out.println(s)); + sayHi(System.out::println); }
рдЬрдм рд╣рдо рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмрд╛рдпрдЯреЗрдХреЛрдб рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдВрддрд░ рджреЗрдЦреЗрдВрдЧреЗ:
[000268] -$$Lambda$1Osqr2Z9OSwjseX_0FMQJcCG_uM.log:(Ljava/lang/String;)V 0000: iget-object v0, v1, L-$$Lambda$1Osqr2Z9OSwjseX_0FMQJcCG_uM;.f$0:Ljava/io/PrintStream; 0002: invoke-virtual {v0, v2}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V 0005: return-void
рдЙрддреНрдкрдиреНрди
Java8.lambda$main$0
рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЬрд┐рд╕рдореЗрдВ
System.out.println
рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдм
System.out.println
рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рдЕрдм рдПрдХ
static
рдПрдХрд▓ рдирд╣реАрдВ рд░рд╣ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрдВрдбреЗрдХреНрд╕
0000
рджреНрд╡рд╛рд░рд╛ рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ
PrintStream
-
System.out
рд▓рд┐рдВрдХ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬреЛ рддрдм рдЙрд╕ рдкрд░
PrintStream
рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдЗрд╕ рдореЗрдВ рдмрджрд▓ рдЧрдИ:
public static void main(String... args) { - sayHi(System.out::println); + sayHi(new -$$Lambda$1Osqr2Z9OSwjseX_0FMQJcCG_uM(System.out)); } @@ } + +class -$$Lambda$1Osqr2Z9OSwjseX_0FMQJcCG_uM implements Java8.Logger { + private final PrintStream ps; + + -$$Lambda$1Osqr2Z9OSwjseX_0FMQJcCG_uM(PrintStream ps) { + this.ps = ps; + } + + @Override public void log(String s) { + ps.println(s); + } +}
рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ Default
рдФрд░ static
рддрд░реАрдХреЗ
рдПрдХ рдФрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдФрд░ рдкреНрд░рдореБрдЦ рдмрджрд▓рд╛рд╡ рдЬреЛ рдЬрд╛рд╡рд╛ 8 рд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рд╡рд╣ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ
default
рдФрд░
static
рддрд░реАрдХреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдерд╛ред
interface Logger { void log(String s); default void log(String tag, String s) { log(tag + ": " + s); } static Logger systemOut() { return System.out::println; } }
рдпрд╣ рд╕рдм D8 рджреНрд╡рд╛рд░рд╛ рднреА рд╕рдорд░реНрдерд┐рдд рд╣реИред рдкрд╣рд▓реЗ рдХреЗ рд╕рдорд╛рди рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛,
default
рдФрд░
static
рддрд░реАрдХреЛрдВ рд╕реЗ рд▓реЙрдЧрд░ рдХреЗ рд▓реЙрдЧ-рдЗрди рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рд▓реИрдореНрдмреНрдбрд╛ рдФрд░
method references
рдореЗрдВ рд╕реЗ рдПрдХ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рд╡реАрдПрдо рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдФрд░ рд╕реНрдерд┐рд░ рддрд░реАрдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░, 24 рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдбреА 8 рдЙрдиреНрд╣реЗрдВ
рдХрдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рд╢рд╛рдпрдж рдХреЛрдЯрд▓рд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ?
рд▓реЗрдЦ рдкрдврд╝рддреЗ рд╣реБрдП, рдЖрдк рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдиреЗ рд╢рд╛рдпрдж рдХреЛрдЯрд▓рд┐рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдерд╛ред рд╣рд╛рдВ, рдпрд╣ рд╕рднреА рдЬрд╛рд╡рд╛ 8 рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрдиреНрд╣реЗрдВ рдХреБрдЫ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдбреА 8 рдХреЗ рд░реВрдк рдореЗрдВ
kotlinc
рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛
kotlinc
рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдЬрд╛рд╡рд╛ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдВрдбреНрд░реЙрдЗрдб рд╕рдорд░реНрдерди рдЕрднреА рднреА рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рднрд▓реЗ рд╣реА рдЖрдкрдХрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛрдЯрд▓рд┐рди рдореЗрдВ 100% рд▓рд┐рдЦрд╛ рд╣реЛред
рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХреЛрдЯрд▓реАрди рдЬрд╛рд╡рд╛ 6 рдФрд░ рдЬрд╛рд╡рд╛ 7 рдмрд╛рдпреЛрдЯреЗрдХ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ред
рдЗрдВрдЯреЗрд▓реАрдЬреЗ рдЖрдИрдбреАрдИрдП , рдЧреНрд░реИрдбрд▓ 5.0 рдЬрд╛рд╡рд╛ рдкрд░ рд╕реНрд╡рд┐рдЪ рд╣реЛ рдЧрдпрд╛ред рдкреБрд░рд╛рдиреЗ рдЬреЗрд╡реАрдПрдо рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрдо рд╣реЛ рд░рд╣реА рд╣реИред
API рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛
рдЗрд╕ рдмрд╛рд░ рдореИрдВрдиреЗ рдЬрд╛рд╡рд╛ 8 рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА, рд▓реЗрдХрд┐рди рдирдП рдПрдкреАрдЖрдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд╣рд╛ - рдзрд╛рд░рд╛рдПрдВ,
CompletableFuture
, рджрд┐рдирд╛рдВрдХ / рд╕рдордп рдФрд░ рдЗрд╕реА рддрд░рд╣ред
рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд▓реМрдЯрддреЗ рд╣реБрдП, рд╣рдо рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдирдИ рддрд┐рдерд┐ / рд╕рдордп рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
import java.time.*; class Java8 { interface Logger { void log(LocalDateTime time, String s); } public static void main(String... args) { sayHi((time, s) -> System.out.println(time + " " + s)); } private static void sayHi(Logger logger) { logger.log(LocalDateTime.now(), "Hello!"); } }
рдЗрд╕реЗ
javac
рд╕рд╛рде рдлрд┐рд░ рд╕реЗ
рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ D8 рдХреЗ рд╕рд╛рде Dalvik bytecode рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВ, рдЬреЛ API рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рд╕рдорд░реНрдерди рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ
рдбрд┐рдХреЙрдЙрдВрдЯ рдХрд░рддрд╛ рд╣реИред
$ javac *.java $ java -jar d8.jar \ --lib $ANDROID_HOME/platforms/android-28/android.jar \ --release \ --output . \ *.class
рдЖрдк рдЗрд╕реЗ рдЕрдкрдиреЗ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рднреА рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
$ adb push classes.dex /sdcard classes.dex: 1 file pushed. 0.5 MB/s (1620 bytes in 0.003s) $ adb shell dalvikvm -cp /sdcard/classes.dex Java8 2018-11-19T21:38:23.761 Hello
рдпрджрд┐ API 26 рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдж рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рд╣реИ, рддреЛ рд╣реИрд▓реЛ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЗрдЦреЗрдВрдЧреЗ:
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/LocalDateTime; at Java8.sayHi(Java8.java:13) at Java8.main(Java8.java:9)
D8 рдиреЗ рд▓реИрдореНрдмреНрдбрд╛, рдПрдХ рд░реЗрдлрд░реЗрдВрд╕ рдореЗрдердб рд╕реЗ рдирд┐рдкрдЯрд╛, рд▓реЗрдХрд┐рди
LocalDateTime
рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдФрд░ рдпрд╣ рдмрд╣реБрдд рджреБрдЦрдж рд╣реИред
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рддрд╛рд░реАрдЦ / рд╕рдордп
ThreeTenBP
рдкрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпрд╛ рд░реИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
ThreeTenBP
, рдпрд╛ рд╕рдордп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
ThreeTenBP
рдЬреИрд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
ThreeTenBP
рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рдбреА 8 рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ?
рдЙрдкрд╕рдВрд╣рд╛рд░
рд╕рднреА рдирдП рдЬрд╛рд╡рд╛ 8 рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреА рдХрдореА Android рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдореЗрдВ рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдмрдиреА рд╣реБрдИ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рдо рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд╣рдореЗрдВ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ 26 рдорд┐рдирдЯ рдПрдкреАрдЖрдИ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддрд╛ рд╣реИред рдПрдВрдбреНрд░реЙрдЗрдб рдФрд░ JVM рджреЛрдиреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп 5 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдкреЗрд╢ рдХрд┐рдП рдЧрдП рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!
рдФрд░ рднрд▓реЗ рд╣реА Java 8 рд╕рдкреЛрд░реНрдЯ рдЕрдм D8 рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдлрд┐рд░ рднреА рд╣рд░ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЬрд╛рд╡рд╛ рдореЗрдВ рд╕реНрд░реЛрдд рдФрд░ рд▓рдХреНрд╖реНрдп рд╕рдВрдЧрддрддрд╛ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЬрд╛рд╡рд╛ 8 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдмрд┐рдЫрд╛рдХрд░ рдЗрд╕ рдкреНрд░рд╡реГрддреНрддрд┐ рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред (рднрд▓реЗ рд╣реА рдЖрдк рдирдИ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ)ред
рдбреА 8 рдкрд░ рдмрд╣реБрдд рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рднрд╛рд╖рд╛ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд╕рдорд░реНрдерди рд╕реЗ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛрдЧрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рдЖрдк рдХреЗрд╡рд▓ рдХреЛрдЯрд▓рд┐рди рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рдЯреАрдо рдХреЛ рдЬрд╛рд╡рд╛ рдХреЗ рд╕рднреА рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рдирд╛, рдмрд╛рдИрдЯреЗрдХреЛрдб рдФрд░ рдирдП рдПрдкреАрдЖрдИ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред
рдпрд╣ рдкреЛрд╕реНрдЯ
D8 рдФрд░ R8 рдореЗрдВ рдореЗрд░реА рдмрд╛рдд
рдЦреЛрджрдиреЗ рдХрд╛ рдПрдХ рд▓рд┐рдЦрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИред