Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Invokedynamic£ºJavaµÄÃØÃÜÎäÆ÷
 
À´Ô´£ºinfoq ×÷Õß £º Ben Evans ·¢²¼ÓÚ 2017-4-7
  2710  次浏览      28
 

ÔÚJava 7µÄ·¢²¼°æÖаüº¬Á˶àÏîеÄÌØÐÔ£¬ÕâÐ©ÌØÐÔÕ§¿´ÉÏÈ¥Java¿ª·¢ÈËÔ±¶ÔËüÃǵÄʹÓ÷dz£ÓÐÏÞ£¬ÔÚÎÒÃÇ֮ǰµÄÎÄÕÂÖУ¬Ôø¾­¶ÔÆä½øÐйý½éÉÜ¡£

µ«ÊÇ£¬ÆäÖÐÓÐÏîÌØÐÔ¶ÔÓÚʵÏÖJava 8ÖС°Í·°æ±êÌ⡱ÀàÐ͵ÄÌØÐÔÀ´ËµÖÁ¹ØÖØÒª£¨ÈçlambdasºÍĬÈÏ·½·¨£©¡£ÔÚ±¾ÎÄÖУ¬ÎÒÃǽ«»áÉîÈëѧϰinvokedynamic£¬²¢²ûÊöËü¶ÔÓÚJavaƽ̨ÒÔ¼°ÏñJRubyºÍNashornÕâÑùµÄJVMÓïÑÔÀ´½²ÎªºÎÈç´ËÖØÒª¡£

invokedynamic×î³õµÄ¹¤×÷ÖÁÉÙʼÓÚ2007Ä꣬¶øµÚÒ»´Î³É¹¦µÄ¶¯Ì¬µ÷Ó÷¢ÉúÔÚ2008Äê8ÔÂ26ÈÕ¡£Õâ±ÈOracleÊÕ¹ºSun»¹ÒªÔ磬°´ÕÕ´ó¶àÊý¿ª·¢ÈËÔ±µÄ±ê×¼£¬Õâ¸öÌØÐÔµÄÑз¢ÒѾ­³ÖÐøÁËÏ൱³¤µÄʱ¼ä¡£

Ïà¹Ø³§ÉÌÄÚÈÝ

¼Ü¹¹Ê¦Ó¦¸Ã°ÑÎÕÕâЩ¼¼ÊõÇ÷ÊÆ100¸öÐÞÁ¶³É¼¼Êõ´ó¿§µÄÃû¶î£¬¾ÍµÈÄãÀ´£¡¡°ÎåÔÆ³öá¶£¬Ë½È˶©ÖÆ¡±UCloud UCan¼¼ÊõÖ®Ò¹£¬µÈÄãÀ´Ô¼µÎµÎ³öÐÐiOS¶ËÊÝÉíʵ¼ùÁÄÍê´óÊý¾Ý¸ÅÄÎÒÃÇÔÙÀ´Ì¸Ì¸´óÊý¾ÝÓ¦ÓÃ

ÖµµÃ×¢ÒâµÄÊÇ£¬´ÓJava 1.0µ½ÏÖÔÚ£¬invokedynamicÊǵÚÒ»¸öмÓÈëµÄJava×Ö½ÚÂ룬ËüÓëÒÑÓеÄ×Ö½ÚÂëinvokevirtual¡¢invokestatic¡¢invokeinterfaceºÍinvokespecial×éºÏÔÚÁËÒ»Æð¡£ÒÑÓеÄÕâËĸö²Ù×÷ÂëʵÏÖÁËJava¿ª·¢ÈËÔ±ËùÊìÖªµÄËùÓÐÐÎʽµÄ·½·¨·ÖÅÉ£¨dispatch£©£º

1.invokevirtual¡ª¡ª¶ÔʵÀý·½·¨µÄ±ê×¼·ÖÅÉ

2.invokestatic¡ª¡ªÓÃÓÚ·ÖÅɾ²Ì¬·½·¨

3.invokeinterface¡ª¡ªÓÃÓÚͨ¹ý½Ó¿Ú½øÐз½·¨µ÷ÓõķÖÅÉ

4.invokespecial¡ª¡ªµ±ÐèÒª½øÐзÇÐ飨Ҳ¾ÍÊÇ¡°¾«È·¡±£©·ÖÅÉʱ»áÓõ½

ÓÐЩ¿ª·¢ÈËÔ±¿ÉÄÜ»áºÃÆæÆ½Ì¨ÎªºÎÐèÒªÕâËÄÖÖ²Ù×÷Â룬ËùÒÔÎÒÃÇ¿´Ò»¸ö¼òµ¥µÄÑùÀý£¬Õâ¸öÑùÀý»áÓõ½²»Í¬µÄµ÷ÓòÙ×÷Â룬ÒÔ´ËÀ´²ûÊöËüÃÇÖ®¼äµÄ²îÒ죺

public class InvokeExamples {

public static void main(String[] args) {

InvokeExamples sc = new InvokeExamples();

sc.run();

}

private void run() {

List ls = new ArrayList();

ls.add("Good Day");

ArrayList als = new ArrayList();

als.add("Dydh Da");

}

}

ÎÒÃÇ¿ÉÒÔʹÓÃjavap·´»ã±à´Ó¶øµÃµ½ËüËù²úÉúµÄ×Ö½ÚÂ룺

javap -c InvokeExamples.class

public class kathik.InvokeExamples {

public kathik.InvokeExamples();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: return

public static void main(java.lang.String[]);

Code:

0: new #2 // class kathik/InvokeExamples

3: dup

4: invokespecial #3 // Method "":()V

7: astore_1

8: aload_1

9: invokespecial #4 // Method run:()V

12: return

private void run();

Code:

0: new #5 // class java/util/ArrayList

3: dup

4: invokespecial #6 // Method java/util/ArrayList."":()V

7: astore_1

8: aload_1

9: ldc #7 // String Good Day

11: invokeinterface #8, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

16: pop

17: new #5 // class java/util/ArrayList

20: dup

21: invokespecial #6 // Method java/util/ArrayList."":()V

24: astore_2

25: aload_2

26: ldc #9 // String Dydh Da

28: invokevirtual #10 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z

31: pop

32: return

}

ÔÚÕâ¸öʾÀýÖУ¬Õ¹ÏÖÁËËĸöµ÷ÓòÙ×÷ÂëÖеÄÈý¸ö£¨Ê£ÏµÄÒ»¸öÒ²¾ÍÊÇinvokestatic£¬ÊÇÒ»¸ö·Ç³£¼òµ¥µÄÀ©Õ¹£©¡£×÷Ϊ¿ªÊ¼£¬ÎÒÃÇ¿ÉÒÔ¿´Ò»ÏÂÈçϵÄÁ½¸öµ÷Óã¨ÔÚrun·½·¨µÄ×Ö½Ú11ºÍ28£©£º

ls.add("Good Day")

ºÍ

als.add("Dydh Da")

ÔÚJavaÔ´ÂëÖÐËüÃÇ¿´ÆðÀ´·Ç³£ÏàËÆ£¬µ«ËüÃÇʵ¼ÊÉÏÈ´´ú±íÁ½ÖÖ²»Í¬µÄ×Ö½ÚÂë¡£

¶ÔÓÚjavacÀ´Ëµ£¬±äÁ¿ls¾ßÓеľ²Ì¬ÀàÐÍÊÇList<String>£¬¶øListÊÇÒ»¸ö½Ó¿Ú¡£ËùÒÔ£¬ÔÚÔËÐÐʱ·½·¨±í£¨Í¨³£³ÆÎª¡°vtable¡±£©ÖУ¬add()·½·¨µÄ¾«È·Î»Öû¹Ã»ÓÐÔÚ±àÒëʱȷ¶¨¡£Òò´Ë£¬Ô´Âë±àÒëÆ÷»áÉú³ÉÒ»¸öinvokeinterfaceÖ¸Á½«Êµ¼ÊµÄ·½·¨²éÕÒÍÆ³Ùµ½ÔËÐÐÆÚ£¬Ò²¾ÍÊǵ±lsµÄʵ¼ÊvtableÄܹ»Ì½²éµ½²¢ÇÒadd()·½·¨µÄλÖÃÄܹ»ÕÒµ½µÄʱºò¡£

ÓëÖ®Ïà·´£¬¶Ôals.add("Dydh Da")µÄµ÷ÓÃÊÇͨ¹ýalsÀ´Ö´Ðеģ¬ÕâÀïµÄ¾²Ì¬ÀàÐÍÊÇÀàÀàÐÍ£¨class type£©¡ª¡ªArrayList<String>¡£ÕâÒâζ×ÅÔÚvtableÖУ¬·½·¨µÄλÖÃÔÚ±àÒëÆÚÊÇ¿ÉÖªµÄ¡£Òò´Ë£¬javac»áÕë¶ÔÕâ¸ö¾«È·µÄvtableÌõÄ¿Éú³ÉÒ»¸öinvokevirtualÖ¸Áî¡£²»¹ý£¬×îÖյķ½·¨Ñ¡ÔñÒÀÈ»ÊÇÔÚÔËÐÐÆÚÈ·¶¨µÄ£¬ÒòΪÕâÀﻹÓз½·¨ÖØÐ´£¨overriding£©µÄ¿ÉÄÜÐÔ£¬µ«ÊÇvtable slotÔÚ±àÒëÆÚ¾ÍÒѾ­È·¶¨ÁË¡£

³ý´ËÖ®Í⣬Õâ¸öÑùÀý»¹Õ¹ÏÖÁËinvokespecialµÄÁ½¸öʹÓó¡¾°¡£Õâ¸ö²Ù×÷ÂëÓÃÓÚÔÚÔËÐÐʱȷ¶¨ÈçºÎ·ÖÅɵij¡¾°Ö®ÖУ¬¾ßÌåÀ´½²£¬ÔÚÕâÀïûÓз½·¨ÖØÐ´µÄÐèÇó£¬ÁíÍâÕâÒ²²»¿ÉÄÜʵÏÖ¡£ÑùÀýÖÐËù²ûÊöµÄ³¡¾°ÊÇprivate methodsºÍsuper calls£¬ÕâЩ·½·¨ÔÚ±àÒëÆÚÊÇ¿ÉÖªµÄ£¬²¢ÇÒÎÞ·¨½øÐÐÖØÐ´¡£

ϸÐĵĶÁÕß¿ÉÄÜÒѾ­·¢ÏÖ£¬¶ÔJava·½·¨µÄËùÓе÷Óö¼±àÒë³ÉÁËËĸö²Ù×÷ÂëÖеÄijһ¸ö£¬ÄÇôÎÊÌâ¾ÍÀ´ÁË¡ª¡ªinvokedynamicÊÇ×öʲôµÄ£¬Ëü¶ÔÓÚJava¿ª·¢ÈËÔ±ÓÐʲôÓô¦ÄØ£¿

Õâ¸öÌØÐÔµÄÖ÷ҪĿ±êÔÚÓÚ´´½¨Ò»¸ö×Ö½ÚÂ룬ÓÃÓÚ´¦ÀíÐÂÐ͵ķ½·¨·ÖÅÉ¡ª¡ªËüµÄ±¾ÖÊÊÇÔÊÐíÓ¦Óü¶±ðµÄ´úÂëÀ´È·¶¨Ö´ÐÐÄÄÒ»¸ö·½·¨µ÷Óã¬Ö»ÓÐÔÚµ÷ÓÃÒªÖ´ÐеÄʱºò£¬²Å»á½øÐÐÕâÖÖÅжϡ£ÕâÑùµÄ»°£¬Ïà¶ÔÓÚJavaƽ̨֮ǰËùÌṩµÄ±à³Ì·ç¸ñ£¬ÔÊÐíÓïÑԺͿò¼ÜµÄ±àдÈËÔ±Ö§³Ö¸ü¼Ó¶¯Ì¬µÄ±àÂë·ç¸ñ¡£

ËüµÄÄ¿µÄÔÚÓÚÓÉÓû§´úÂëͨ¹ý·½·¨¾ä±úAPI£¨method handles API£©ÔÚÔËÐÐʱȷ¶¨ÈçºÎ·ÖÅÉ£¬Í¬Ê±±ÜÃâ·´Éä´øÀ´µÄÐÔÄܳͷ£ºÍ°²È«ÎÊÌ⡣ʵ¼ÊÉÏ£¬invokedynamicËùÐû³ÆµÄÄ¿±ê¾ÍÊÇÒ»µ©¸ÃÌØÐÔ×ã¹»³ÉÊ죬ËüµÄËÙ¶ÈÒªÏñ³£¹æµÄ·½·¨·ÖÅÉ£¨invokevirtual£©Ò»Ñù¿ì¡£

µ±Java 7·¢²¼µÄʱºò£¬JVM¾ÍÒѾ­Ö§³ÖÖ´ÐÐеÄ×Ö½ÚÂëÁË£¬µ«ÊDz»¹ÜÌύʲôÑùµÄJava´úÂ룬javac¶¼²»»á²úÉú°üº¬invokedynamicµÄ×Ö½ÚÂë¡£ÕâÏîÌØÐÔÓÃÀ´Ö§³ÖJRubyºÍÆäËûÔËÐÐÔÚJVMÉϵĶ¯Ì¬ÓïÑÔ¡£

ÔÚJava 8ÖУ¬Õâ·¢ÉúÁ˱仯£¬ÔÚʵÏÖlambda±í´ïʽºÍĬÈÏ·½·¨Ê±£¬µ×²ã»áÉú³ÉºÍʹÓÃinvokedynamic£¬Ëüͬʱ»¹»á×÷ΪNashornµÄÊ×Ñ¡·ÖÅÉ»úÖÆ¡£µ«ÊÇ£¬¶ÔÓÚJavaÓ¦ÓõĿª·¢ÈËÔ±À´Ëµ£¬ÒÀȻûÓÐÖ±½ÓµÄ·½Ê½ÊµÏÖÍêÈ«µÄ¶¯Ì¬·½·¨´¦Àí£¨resolution£©¡£Ò²¾ÍÊÇ˵£¬JavaÓïÑÔ²¢Ã»ÓÐÌṩ¹Ø¼ü×Ö»ò¿âÀ´´´½¨Í¨ÓõÄinvokedynamicµ÷Óõ㣨call site£©¡£ÕâÒâζ×Å£¬¾¡¹ÜÕâÖÖ»úÖÆµÄ¹¦Äܷdz£Ç¿´ó£¬µ«Ëü¶ÔÓÚ´ó¶àÊýµÄJava¿ª·¢ÈËÔ±À´ËµÒÀÈ»ÓÐЩİÉú¡£½ÓÏÂÀ´£¬ÎÒÃÇ¿´Ò»ÏÂÈçºÎÔÚ×Ô¼ºµÄ´úÂëÖÐʹÓÃÕâÏî¼¼Êõ¡£

·½·¨¾ä±ú¼ò½é

ÒªÈÃinvokedynamicÕý³£ÔËÐУ¬Ò»¸öºËÐĵĸÅÄî¾ÍÊÇ·½·¨¾ä±ú£¨method handle£©¡£Ëü´ú±íÁËÒ»¸ö¿ÉÒÔ´Óinvokedynamicµ÷ÓÃµã½øÐе÷Óõķ½·¨¡£ÕâÀïµÄ»ù±¾ÀíÄî¾ÍÊÇÿ¸öinvokedynamicÖ¸Áî¶¼»áÓëÒ»¸öÌØ¶¨µÄ·½·¨¹ØÁª£¨Ò²¾ÍÊÇÒýµ¼·½·¨»òBSM£©¡£µ±½âÊÍÆ÷£¨interpreter£©Óöµ½invokedynamicÖ¸ÁîµÄʱºò£¬BSM»á±»µ÷Óá£Ëü»á·µ»ØÒ»¸ö¶ÔÏ󣨰üº¬ÁËÒ»¸ö·½·¨¾ä±ú£©£¬Õâ¸ö¶ÔÏó±íÃ÷Á˵÷ÓõãҪʵ¼ÊÖ´ÐÐÄĸö·½·¨¡£

ÔÚÒ»¶¨³Ì¶ÈÉÏ£¬ÕâÓë·´ÉäÓÐЩÀàËÆ£¬µ«ÊÇ·´ÉäÓÐËüµÄ¾ÖÏÞÐÔ£¬ÕâЩ¾ÖÏÞÐÔʹËü²»ÊʺÏÓëinvokedynamicЭ×÷ʹÓá£Java 7 APIÖмÓÈëÁËjava.lang.invoke.MethodHandle£¨¼°Æä×ÓÀࣩ£¬Í¨¹ýËüÃÇÀ´´ú±íinvokedynamicÖ¸ÏòµÄ·½·¨¡£ÎªÁËʵÏÖ²Ù×÷µÄÕýÈ·ÐÔ£¬MethodHandle»áµÃµ½JVMµÄÒ»Ð©ÌØÊâ´¦Àí¡£

Àí½â·½·¨¾ä±úµÄÒ»ÖÖ·½Ê½¾ÍÊǽ«ÆäÊÓΪÒÔ°²È«¡¢ÏÖ´úµÄ·½Ê½À´ÊµÏÖ·´ÉäµÄºËÐŦÄÜ£¬ÔÚÕâ¸ö¹ý³Ì»á¾¡¿ÉÄܵر£Ö¤ÀàÐ͵ݲȫ¡£invokedynamicÐèÒª·½·¨¾ä±ú£¬ÁíÍâËüÃÇÒ²¿ÉÒÔµ¥¶ÀʹÓá£

·½·¨ÀàÐÍ

Ò»¸öJava·½·¨¿ÉÒÔÊÓΪÓÉËĸö»ù±¾ÄÚÈÝËù¹¹³É£º

Ãû³Æ

Ç©Ãû£¨°üº¬·µ»ØÀàÐÍ£©

¶¨ÒåËüµÄÀà

ʵÏÖ·½·¨µÄ×Ö½ÚÂë

ÕâÒâζ×ÅÈç¹ûÒªÒýÓÃij¸ö·½·¨£¬ÎÒÃÇÐèÒªÓÐÒ»ÖÖÓÐЧµÄ·½Ê½À´±íʾ·½·¨Ç©Ãû£¨¶ø²»ÊÇ·´ÉäÖÐÇ¿ÖÆÊ¹ÓõÄÁîÈËÌÖÑáµÄClass<?>[] hack·½Ê½£©¡£

½ÓÏÂÀ´ÎÒÃDzÉÓÃÁíÍâµÄ·½Ê½£¬·½·¨¾ä±úÊ×ÏÈÐèÒªµÄÒ»¸ö¹¹½¨¿é¾ÍÊDZí´ï·½·¨Ç©ÃûµÄ·½Ê½£¬ÒÔ±ãÓÚ²éÕÒ¡£ÔÚJava 7ÒýÈëµÄMethod Handles APIÖУ¬Õâ¸ö½ÇÉ«ÊÇÓÉjava.lang.invoke.MethodTypeÀàÀ´Íê³ÉµÄ£¬ËüʹÓÃÒ»¸ö²»¿É±äµÄʵÀýÀ´´ú±íÇ©Ãû¡£Òª»ñÈ¡MethodType£¬ÎÒÃÇ¿ÉÒÔʹÓÃmethodType()¹¤³§·½·¨¡£ÕâÊÇÒ»¸ö²ÎÊý¿É±ä£¨variadic£©µÄ·½·¨£¬ÒÔclass¶ÔÏó×÷Ϊ²ÎÊý¡£

µÚÒ»¸ö²ÎÊýËùʹÓõÄclass¶ÔÏ󣬶ÔÓ¦×ÅÇ©ÃûµÄ·µ»ØÀàÐÍ£»Ê£Óà²ÎÊýÖÐËùʹÓõÄclass¶ÔÏ󣬶ÔÓ¦×ÅÇ©ÃûÖз½·¨²ÎÊýµÄÀàÐÍ¡£ÀýÈ磺

//toString()µÄÇ©Ãû

MethodType mtToString = MethodType.methodType(String.class)

// setter·½·¨µÄÇ©Ãû

MethodType mtSetter = MethodType.methodType(void.class, Object.class);

// ComparatorÖÐcompare()·½·¨µÄÇ©Ãû

MethodType mtStringComparator = MethodType.methodType(int.class, String.class,

ÏÖÔÚÎÒÃǾͿÉÒÔʹÓÃMethodType£¬ÔÙ×éºÏ·½·¨Ãû³ÆÒÔ¼°¶¨Òå·½·¨µÄÀàÀ´²éÕÒ·½·¨¾ä±ú¡£ÒªÊµÏÖÕâÒ»µã£¬ÎÒÃÇÐèÒªµ÷Óþ²Ì¬µÄMethodHandles.lookup()·½·¨¡£ÕâÑùµÄ»°£¬»á¸øÎÒÃÇÒ»¸ö¡°²éÕÒÉÏÏÂÎÄ£¨lookup context£©¡±£¬Õâ¸öÉÏÏÂÎÄ»ùÓÚµ±Ç°ÕýÔÚÖ´Ðеķ½·¨£¨Ò²¾ÍÊǵ÷ÓÃlookup()µÄ·½·¨£©µÄ·ÃÎÊȨÏÞ¡£

²éÕÒÉÏÏÂÎĶÔÏóÓÐһЩÒÔ¡°find¡±¿ªÍ·µÄ·½·¨£¬ÀýÈ磬findVirtual()¡¢findConstructor()¡¢findStatic()µÈ¡£ÕâЩ·½·¨½«»á·µ»ØÊµ¼ÊµÄ·½·¨¾ä±ú£¬ÐèҪעÒâµÄÊÇ£¬Ö»ÓÐÔÚ´´½¨²éÕÒÉÏÏÂÎĵķ½·¨Äܹ»·ÃÎÊ£¨µ÷Ó㩱»ÇëÇó·½·¨µÄÇé¿öÏ£¬²Å»á·µ»Ø¾ä±ú¡£ÕâÓë·´É䲻ͬ£¬ÎÒÃÇûÓÐ°ì·¨ÈÆ¹ý·ÃÎÊ¿ØÖÆ¡£»»¾ä»°Ëµ£¬·½·¨¾ä±úÖв¢Ã»ÓÐÓësetAccessible()¶ÔÓ¦µÄ·½·¨¡£ÀýÈ磺

public MethodHandle getToStringMH() {

MethodHandle mh = null;

MethodType mt = MethodType.methodType(String.class);

MethodHandles.Lookup lk = MethodHandles.lookup();

try {

mh = lk.findVirtual(getClass(), "toString", mt);

} catch (NoSuchMethodException | IllegalAccessException mhx) {

throw (AssertionError)new AssertionError().initCause(mhx);

}

return mh;

}

MethodHandleÖÐÓÐÁ½¸ö·½·¨Äܹ»´¥·¢¶Ô·½·¨¾ä±úµÄµ÷Óã¬ÄǾÍÊÇinvoke()ºÍinvokeExact()¡£ÕâÁ½¸ö·½·¨¶¼ÊÇÒÔ½ÓÊÕÕߣ¨receiver£©ºÍµ÷ÓñäÁ¿×÷Ϊ²ÎÊý£¬ËùÒÔËüÃǵÄÇ©ÃûΪ£º

public final Object invoke(Object... args) throws Throwable;

public final Object invokeExact(Object... args) throws Throwable;

Á½ÕßµÄÇø±ðÔÚÓÚ£¬invokeExact()ÔÚµ÷Ó÷½·¨¾ä±úʱ»áÊÔͼÑϸñµØÖ±½ÓÆ¥ÅäËùÌṩµÄ±äÁ¿¡£¶øinvoke()ÓëÖ®²»Í¬£¬ÔÚÐèÒªµÄʱºò£¬invoke()Äܹ»ÉÔ΢µ÷ÕûһϷ½·¨µÄ±äÁ¿¡£invoke()»áÖ´ÐÐÒ»¸öasType()ת»»£¬Ëü»á¸ù¾ÝÈçϵÄÕâ×鹿ÔòÀ´½øÐбäÁ¿µÄת»»£º

Èç¹ûÐèÒªµÄ»°£¬Ô­Ê¼ÀàÐÍ»á½øÐÐ×°Ïä²Ù×÷

Èç¹ûÐèÒªµÄ»°£¬×°ÏäºóµÄԭʼÀàÐÍ»á½øÐвðÏä²Ù×÷

Èç¹û±ØÒªµÄ»°£¬Ô­Ê¼ÀàÐÍ»á½øÐÐÀ©Õ¹

void·µ»ØÀàÐÍ»áת»»Îª0£¨¶ÔÓÚ·µ»ØÔ­Ê¼ÀàÐ͵ÄÇé¿ö£©£¬¶ø¶ÔÓÚÔ¤ÆÚµÃµ½ÒýÓÃÀàÐ͵ķµ»ØÖµµÄµØ·½£¬½«»áת»»Îªnull

nullÖµ»á±»ÊÓΪÕýÈ·µÄ£¬²»¹Ü¾²Ì¬ÀàÐÍÊÇʲô¶¼¿ÉÒÔ½øÐд«µÝ

½ÓÏÂÀ´£¬ÎÒÃÇ¿´Ò»Ï¿¼ÂÇÉÏÊö¹æÔòµÄ¼òµ¥µ÷ÓÃÑùÀý£º

Object rcvr = "a";

try {

MethodType mt = MethodType.methodType(int.class);

MethodHandles.Lookup l = MethodHandles.lookup();

MethodHandle mh = l.findVirtual(rcvr.getClass(), "hashCode", mt);

int ret;

try {

ret = (int)mh.invoke(rcvr);

System.out.println(ret);

} catch (Throwable t) {

t.printStackTrace();

}

} catch (IllegalArgumentException | NoSuchMethodException | SecurityException e) {

e.printStackTrace();

} catch (IllegalAccessException x) {

x.printStackTrace();

}

ÔÚ¸üΪ¸´ÔÓµÄÑùÀýÖУ¬·½·¨¾ä±úÄܹ»ÒÔ¸üÇåÎúµÄ·½Ê½À´Ö´ÐÐÓëºËÐÄ·´É书ÄÜÏàͬµÄ¶¯Ì¬±à³ÌÈÎÎñ¡£³ý´ËÖ®Í⣬ÔÚÉè¼ÆÖ®³õ£¬·½·¨¾ä±ú¾ÍÓëJVMµ×²ãµÄÖ´ÐÐÄ£ÐÍЭ×÷µØ¸üºÃ£¬²¢ÇÒ¿ÉÄÜ»áÌṩ¸üºÃµÄÐÔÄÜ£¨¾¡¹ÜÐÔÄܵÄÎÊÌ⻹ûÓÐÕ¹¿ªÐðÊö£©¡£

·½·¨¾ä±úÓëinvokedynamic

invokedynamicÖ¸Áîͨ¹ýÒýµ¼·½·¨£¨bootstrap method£¬BSM£©»úÖÆÀ´Ê¹Ó÷½·¨¾ä±ú¡£ÓëinvokevirtualÖ¸Áͬ£¬invokedynamicÖ¸ÁîûÓнÓÊÕÕß¶ÔÏó¡£Ïà·´£¬ËüÃǵÄÐÐΪÀàËÆÓÚinvokestatic£¬»áʹÓÃBSMÀ´·µ»ØÒ»¸öCallSiteÀàÐ͵ĶÔÏó¡£Õâ¸ö¶ÔÏó°üº¬Ò»¸ö·½·¨¾ä±ú£¨³ÆÖ®Îª¡°target¡±£©£¬Ëü´ú±íÁ˵±Ç°invokedynamicÖ¸ÁîÒªÖ´Ðеķ½·¨¡£

µ±°üº¬invokedynamicµÄÀà¼ÓÔØÊ±£¬µ÷Óõã»á´¦ÓÚ¡°unlaced¡±×´Ì¬£¬ÔÚBSM·µ»ØÖ®ºó£¬µÃµ½µÄCallSiteºÍ·½·¨¾ä±ú»áÈõ÷Óõ㴦ÓÚ¡°laced¡±×´Ì¬¡£

BSMµÄÇ©Ãû´óÖ»áÈçÏÂËùʾ£¨×¢Ò⣬BSMµÄÃû³ÆÊÇÈÎÒâµÄ£©£º

static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type);

Èç¹ûÄãÏ£Íû´´½¨°üº¬invokedynamicµÄ´úÂ룬ÄÇôÎÒÃÇÐèҪʹÓÃÒ»¸ö×Ö½ÚÂë²Ù×ݿ⣨ÒòΪJavaÓïÑÔ±¾Éí²¢²»°üº¬ÎÒÃÇËùÐèµÄ¹¹Ô죩¡£ÔÚ±¾ÎÄÊ£ÓàµÄÄÚÈÝÖУ¬ÎÒÃǽ«»áʹÓÃASM¿âÀ´Éú³É°üº¬invokedynamicÖ¸ÁîµÄ×Ö½ÚÂë¡£´ÓJavaÓ¦ÓóÌÐòµÄ½Ç¶ÈÀ´¿´£¬ËüÃÇ¿´ÆðÀ´¾ÍÏñÊdz£¹æµÄÀàÎļþ£¨µ±È»£¬ËüÃÇûÓÐÏà¹ØµÄJavaÔ´Âë±íÊö£©¡£Java´úÂë»á½«ÆäÊÓΪ¡°ºÚºÐ¡±£¬²»¹ýÎÒÃÇ¿ÉÒÔµ÷Ó÷½·¨²¢Ê¹ÓÃinvokedynamic¼°ÆäÏà¹ØµÄ¹¦ÄÜ¡£

ÏÂÃæ£¬ÎÒÃÇÀ´¿´Ò»Ï»ùÓÚASMµÄÀ࣬Ëü»áʹÓÃinvokedynamicÖ¸ÁîÀ´Éú³É¡°Hello World¡±¡£

public class InvokeDynamicCreator {

public static void main(final String[] args) throws Exception {

final String outputClassName = "kathik/Dynamic";

try (FileOutputStream fos

= new FileOutputStream(new File("target/classes/" + outputClassName + ".class"))) {

fos.write(dump(outputClassName, "bootstrap", "()V"));

}

}

public static byte[] dump(String outputClassName, String bsmName, String targetMethodDescriptor)

throws Exception {

final ClassWriter cw = new ClassWriter(0);

MethodVisitor mv;

// ΪÒýµ¼Àà´î½¨»ù±¾µÄÔªÊý¾Ý

cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, outputClassName, null, "java/lang/Object", null);

// ´´½¨±ê×¼µÄvoid¹¹ÔìÆ÷

mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null);

mv.visitCode();

mv.visitVarInsn(ALOAD, 0);

mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V");

mv.visitInsn(RETURN);

mv.visitMaxs(1, 1);

mv.visitEnd();

// ´´½¨±ê×¼µÄmain·½·¨

mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);

mv.visitCode();

MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,

MethodType.class);

Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "kathik/InvokeDynamicCreator", bsmName,

mt.toMethodDescriptorString());

mv.visitInvokeDynamicInsn("runDynamic", targetMethodDescriptor, bootstrap);

mv.visitInsn(RETURN);

mv.visitMaxs(0, 1);

mv.visitEnd();

cw.visitEnd();

return cw.toByteArray();

}

private static void targetMethod() {

System.out.println("Hello World!");

}

public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {

final MethodHandles.Lookup lookup = MethodHandles.lookup();

// ÐèҪʹÓÃlookupClass()£¬ÒòΪÕâ¸ö·½·¨ÊǾ²Ì¬µÄ

final Class currentClass = lookup.lookupClass();

final MethodType targetSignature = MethodType.methodType(void.class);

final MethodHandle targetMH = lookup.findStatic(currentClass, "targetMethod", targetSignature);

return new ConstantCallSite(targetMH.asType(type));

}

}

Õâ¸ö´úÂë·ÖΪÁ½²¿·Ö£¬µÚÒ»²¿·ÖʹÓÃASM Visitor APIÀ´´´½¨ÃûΪkathik.DynamicµÄÀàÎļþ¡£×¢Ò⣬ºËÐĵĵ÷ÓÃÊÇvisitInvokeDynamicInsn()¡£µÚ¶þ²¿·Ö°üº¬ÁËÒªÀ¦°óµ½µ÷ÓõãÖеÄÄ¿±ê·½·¨£¬²¢ÇÒ»¹°üÀ¨invokedynamicÖ¸ÁîËùÐèµÄBSM¡£

×¢Ò⣬ÉÏÊöµÄ·½·¨ÊÇλÓÚInvokeDynamicCreatorÀàÖе쬶ø²»ÊÇËùÉú³ÉµÄkathik.DynamicÀàµÄÒ»²¿·Ö¡£ÕâÒâζ×Å£¬ÔÚÔËÐÐʱ£¬InvokeDynamicCreator±ØÐëÒ²ÒªºÍkathik.DynamicÒ»ÆðλÓÚÀà·¾¶ÖУ¬·ñÔòµÄ»°£¬¾Í»áÎÞ·¨ÕÒµ½·½·¨¡£

µ±InvokeDynamicCreatorÔËÐÐʱ£¬Ëü»á´´½¨Ò»¸öеÄÀàÎļþDynamic.class£¬Õâ¸öÎļþÖаüº¬ÁËinvokedynamicÖ¸Áͨ¹ýÔÚÕâ¸öÀàÉÏÖ´ÐÐjavap£¬ÎÒÃÇ¿ÉÒÔ¿´µ½ÕâÒ»µã£º

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=0, locals=1, args_size=1

0: invokedynamic #20, 0 // InvokeDynamic #0:runDynamic:()V

5: return

Õâ¸öÑùÀý²ûÊöÁËinvokedynamic×î¼òµ¥µÄʹÓó¡¾°£¬Ëü»áʹÓÃÒ»¸öÌØ¶¨µÄ³£Á¿CallSite¶ÔÏó¡£ÕâÒâζ×ÅBSM£¨ºÍlookup£©Ö»»áÖ´ÐÐÒ»´Î£¬ËùÒÔºóÐøµÄµ÷ÓûáºÜ¿ì¡£

µ«ÊÇ£¬Õë¶ÔinvokedynamicµÄ¸ß¼¶Ó÷¨ºÜ¿ì¾Í»á±äµÃ·Ç³£¸´ÔÓ£¬µ±µ÷ÓõãºÍÄ¿±ê·½·¨ÔÚ³ÌÐòÉúÃüÖÜÆÚÖлᷢÉú±ä»¯Ê±¸üÊÇÈç´Ë¡£

   
2710 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö
×îл¼Æ»®
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-28[±±¾©]
OCSMPÈÏÖ¤£ºOCSMP-MBF 8-29[±±¾©]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 9-9[±±¾©]
Èí¼þ¼Ü¹¹Éè¼Æ·½·¨¡¢°¸Àýʵ¼ù 9-24[±±¾©]
ÐèÇó·ÖÎöʦÄÜÁ¦ÅàÑø 10-30[±±¾©]
MBSEÌåϵÓëʵ¼ù 8-26[±±¾©]

Java ÖеÄÖÐÎıàÂëÎÊÌâ
Java»ù´¡ÖªÊ¶µÄÈýÊ®¸ö¾­µäÎÊ´ð
Íæ×ª Java Web Ó¦Óÿª·¢
ʹÓÃSpring¸üºÃµØ´¦ÀíStruts
ÓÃEclipse¿ª·¢iPhone WebÓ¦ÓÃ
²å¼þϵͳ¿ò¼Ü·ÖÎö

Struts+Spring+Hibernate
»ùÓÚJ2EEµÄWeb 2.0Ó¦Óÿª·¢
J2EEÉè¼ÆÄ£Ê½ºÍÐÔÄܵ÷ÓÅ
Java EE 5ÆóÒµ¼¶¼Ü¹¹Éè¼Æ
Javaµ¥Ôª²âÊÔ·½·¨Óë¼¼Êõ
Java±à³Ì·½·¨Óë¼¼Êõ

Struts+Spring+Hibernate/EJB+ÐÔÄÜÓÅ»¯
»ªÏÄ»ù½ð ActiveMQ Ô­ÀíÓë¹ÜÀí
ijÃñº½¹«Ë¾ Java»ù´¡±à³Ìµ½Ó¦Óÿª·¢
ij·çµç¹«Ë¾ Java Ó¦Óÿª·¢Æ½Ì¨ÓëÇ¨ÒÆ
ÈÕÕÕ¸Û J2EEÓ¦Óÿª·¢¼¼Êõ¿ò¼ÜÓëʵ¼ù
ij¿ç¹ú¹«Ë¾ ¹¤×÷Á÷¹ÜÀíJBPM
¶«·½º½¿Õ¹«Ë¾ ¸ß¼¶J2EE¼°ÆäÇ°ÑØ¼¼Êõ