一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Struts2深入學(xué)習(xí):OGNL表達(dá)式原理

 昵稱35534689 2016-08-05
Struts2深入學(xué)習(xí):OGNL表達(dá)式原理
信仰や欺騙  信仰や欺騙的博客  2012-03-08

一、OGNL表達(dá)式基礎(chǔ)知識(shí) 

  1. 示例:第一個(gè)OGNL程序

  2. 示例:上下文環(huán)境中使用OGNL

  3. 示例:使用OGNL調(diào)用方法

  4. 示例:使用OGNL操作集合  

  5. 示例:使用OGNL過濾集合與投影集合

二、OGNL與Struts2

OGNL表達(dá)式

OGNL,全稱為Object-Graph Navigation Language,它是一個(gè)功能強(qiáng)大的表達(dá)式語言,用來獲取和設(shè)置Java對(duì)象的屬性,它旨在提供一個(gè)更高的更抽象的層次來對(duì)Java對(duì)象圖進(jìn)行導(dǎo)航。

OGNL表達(dá)式的基本單位是'導(dǎo)航鏈',一般導(dǎo)航鏈由如下幾個(gè)部分組成:

  1. 屬性名稱(property) 
  2. 方法調(diào)用(method invoke) 
  3. 數(shù)組元素

所有的OGNL表達(dá)式都基于當(dāng)前對(duì)象的上下文來完成求值運(yùn)算,鏈的前面部分的結(jié)果將作為后面求值的上下文。例如:names[0].length()。

示例:第一個(gè)OGNL程序

  1. public class OGNL1  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         /* 創(chuàng)建一個(gè)Person對(duì)象 */ 
  6.         Person person = new Person();  
  7.         person.setName('zhangsan');  
  8.           
  9.         try 
  10.         {  
  11.             /* 從person對(duì)象中獲取name屬性的值 */ 
  12.             Object value = Ognl.getValue('name', person);  
  13.  
  14.             System.out.println(value);  
  15.         }  
  16.         catch (OgnlException e)  
  17.         {  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21. }  
  22.  
  23. class Person  
  24. {  
  25.     private String name;  
  26.  
  27.     public String getName()  
  28.     {  
  29.         return name;  
  30.     }  
  31.  
  32.     public void setName(String name)  
  33.     {  
  34.         this.name = name;  
  35.     }  

控制臺(tái)輸出:

zhangsan

可以看到我們正確的取得了person對(duì)象的name屬性值,該getValue聲明如下:

  1. public static  T getValue(String expression,Object root)throws OgnlException  
  2.  
  3. Convenience method that combines calls to  parseExpression  and  getValue.   
  4.  
  5. Parameters:  
  6. expression - the OGNL expression to be parsed  
  7. root - the root object for the OGNL expression   
  8. Returns:  
  9. the result of evaluating the expression 

OGNL會(huì)根據(jù)表達(dá)式從根對(duì)象(root)中提取值。

示例:上下文環(huán)境中使用OGNL

  1. public class OGNL1  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         /* 創(chuàng)建一個(gè)上下文Context對(duì)象,它是用保存多個(gè)對(duì)象一個(gè)環(huán)境 對(duì)象 */ 
  6.         Map context = new HashMap();  
  7.  
  8.         Person person1 = new Person();  
  9.         person1.setName('zhangsan');  
  10.           
  11.         Person person2 = new Person();  
  12.         person2.setName('lisi');  
  13.  
  14.         Person person3 = new Person();  
  15.         person3.setName('wangwu');  
  16.  
  17.         /* person4不放入到上下文環(huán)境中 */ 
  18.         Person person4 = new Person();  
  19.         person4.setName('zhaoliu');  
  20.  
  21.         /* 將person1、person2、person3添加到環(huán)境中(上下文中) */ 
  22.         context.put('person1', person1);  
  23.         context.put('person2', person2);  
  24.         context.put('person3', person3);  
  25.  
  26.         try 
  27.         {  
  28.             /* 獲取根對(duì)象的'name'屬性值 */ 
  29.             Object value = Ognl.getValue('name', context, person2);  
  30.             System.out.println('ognl expression \'name\' evaluation is : ' + value);  
  31.  
  32.             /* 獲取根對(duì)象的'name'屬性值 */ 
  33.             Object value2 = Ognl.getValue('#person2.name', context, person2);  
  34.             System.out.println('ognl expression \'#person2.name\' evaluation is : ' + value2);  
  35.  
  36.             /* 獲取person1對(duì)象的'name'屬性值 */ 
  37.             Object value3 = Ognl.getValue('#person1.name', context, person2);  
  38.             System.out.println('ognl expression \'#person1.name\' evaluation is : ' + value3);  
  39.  
  40.             /* 將person4指定為root對(duì)象,獲取person4對(duì)象的'name'屬性,注意person4對(duì)象不在上下文中 */ 
  41.             Object value4 = Ognl.getValue('name', context, person4);  
  42.             System.out.println('ognl expression \'name\' evaluation is : ' + value4);  
  43.  
  44.             /* 將person4指定為root對(duì)象,獲取person4對(duì)象的'name'屬性,注意person4對(duì)象不在上下文中 */ 
  45.             Object value5 = Ognl.getValue('#person4.name', context, person4);  
  46.             System.out.println('ognl expression \'person4.name\' evaluation is : ' + value5);  
  47.  
  48.             /* 獲取person4對(duì)象的'name'屬性,注意person4對(duì)象不在上下文中 */ 
  49.             // Object value6 = Ognl.getValue('#person4.name', context, person2);  
  50.             // System.out.println('ognl expression \'#person4.name\' evaluation is : ' + value6);  
  51.  
  52.         }  
  53.         catch (OgnlException e)  
  54.         {  
  55.             e.printStackTrace();  
  56.         }  
  57.     }  
  58. }  
  59.  
  60. class Person  
  61. {  
  62.     private String name;  
  63.  
  64.     public String getName()  
  65.     {  
  66.         return name;  
  67.     }  
  68.  
  69.     public void setName(String name)  
  70.     {  
  71.         this.name = name;  
  72.     }  

控制臺(tái)輸出:

  1. ognl expression 'name' evaluation is : lisi  
  2. ognl expression '#person2.name' evaluation is : lisi  
  3. ognl expression '#person1.name' evaluation is : zhangsan  
  4. ognl expression 'name' evaluation is : zhaoliu  
  5. ognl.OgnlException: source is null for getProperty(null'name')  
  6.     at ognl.OgnlRuntime.getProperty(OgnlRuntime.java:2296)  
  7.     at ognl.ASTProperty.getValueBody(ASTProperty.java:114)  
  8.     at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)  
  9.     at ognl.SimpleNode.getValue(SimpleNode.java:258)  
  10.     at ognl.ASTChain.getValueBody(ASTChain.java:141)  
  11.     at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)  
  12.     at ognl.SimpleNode.getValue(SimpleNode.java:258)  
  13.     at ognl.Ognl.getValue(Ognl.java:494)  
  14.     at ognl.Ognl.getValue(Ognl.java:596)  
  15.     at ognl.Ognl.getValue(Ognl.java:566)  
  16.     at com.beliefbetrayal.ognl.OGNL1.main(OGNL1.java:53

對(duì)于使用上下文的OGNL,若不指定從哪一個(gè)對(duì)象中查找'name'屬性,則OGNL直接從根對(duì)象(root)查找,若指定查找對(duì)象(使用'#'號(hào)指定,如#person1),則從指定的對(duì)象中查找,若指定對(duì)象不在上下文中則會(huì)拋出異常,換句話說就是是#person1.name形式指定查找對(duì)象則必須要保證指定對(duì)象在上下文環(huán)境中。

示例:使用OGNL調(diào)用方法

  1. public class OGNL2  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         /* OGNL提供的一個(gè)上下文類,它實(shí)現(xiàn)了Map接口 */ 
  6.         OgnlContext context = new OgnlContext();  
  7.  
  8.         People people1 = new People();  
  9.         people1.setName('zhangsan');  
  10.  
  11.         People people2 = new People();  
  12.         people2.setName('lisi');  
  13.  
  14.         People people3 = new People();  
  15.         people3.setName('wangwu');  
  16.  
  17.         context.put('people1', people1);  
  18.         context.put('people2', people2);  
  19.         context.put('people3', people3);  
  20.           
  21.         context.setRoot(people1);  
  22.  
  23.         try 
  24.         {  
  25.             /* 調(diào)用 成員方法 */ 
  26.             Object value = Ognl.getValue('name.length()', context, context.getRoot());  
  27.             System.out.println('people1 name length is :' + value);  
  28.               
  29.             Object upperCase = Ognl.getValue('#people2.name.toUpperCase()', context, context.getRoot());  
  30.             System.out.println('people2 name upperCase is :' + upperCase);  
  31.  
  32.             Object invokeWithArgs = Ognl.getValue('name.charAt(5)', context, context.getRoot());  
  33.             System.out.println('people1 name.charAt(5) is :' + invokeWithArgs);  
  34.  
  35.             /* 調(diào)用靜態(tài)方法 */ 
  36.             Object min = Ognl.getValue('@java.lang.Math@min(4,10)', context, context.getRoot());  
  37.             System.out.println('min(4,10) is :' + min);  
  38.  
  39.             /* 調(diào)用靜態(tài)變量 */ 
  40.             Object e = Ognl.getValue('@java.lang.Math@E', context, context.getRoot());  
  41.             System.out.println('E is :' + e);  
  42.         }  
  43.         catch (OgnlException e)  
  44.         {  
  45.             e.printStackTrace();  
  46.         }  
  47.     }  
  48. }  
  49.  
  50. class People  
  51. {  
  52.     private String name;  
  53.  
  54.     public String getName()  
  55.     {  
  56.         return name;  
  57.     }  
  58.  
  59.     public void setName(String name)  
  60.     {  
  61.         this.name = name;  
  62.     }  

控制臺(tái)輸出:

  1. people1 name length is :8 
  2. people2 name upperCase is :LISI  
  3. people1 name.charAt(5) is :s  
  4. min(4,10) is :4 
  5. E is :2.718281828459045 

使用OGNL調(diào)用方法也十分簡(jiǎn)單,對(duì)于成員方法調(diào)用,只需要給出方法的名稱+(),若有參數(shù),直接寫在括號(hào)內(nèi),與一般調(diào)用Java方法一致。對(duì)于靜態(tài)方法的調(diào)用,需要使用如下格式:@ClassName@method,對(duì)于靜態(tài)變量需要使用如下格式:@ClassName@field。

示例:使用OGNL操作集合

  1. public class OGNL3  
  2. {  
  3.     public static void main(String[] args) throws Exception  
  4.     {  
  5.         OgnlContext context = new OgnlContext();  
  6.           
  7.         Classroom classroom = new Classroom();  
  8.         classroom.getStudents().add('zhangsan');  
  9.         classroom.getStudents().add('lisi');  
  10.         classroom.getStudents().add('wangwu');  
  11.         classroom.getStudents().add('zhaoliu');  
  12.         classroom.getStudents().add('qianqi');  
  13.           
  14.         Student student = new Student();  
  15.         student.getContactWays().put('homeNumber''110');  
  16.         student.getContactWays().put('companyNumber''119');  
  17.         student.getContactWays().put('mobilePhone''112');  
  18.           
  19.         context.put('classroom', classroom);  
  20.         context.put('student', student);  
  21.         context.setRoot(classroom);  
  22.  
  23.         /* 獲得classroom的students集合 */ 
  24.         Object collection = Ognl.getValue('students', context, context.getRoot());  
  25.         System.out.println('students collection is :' + collection);  
  26.  
  27.         /* 獲得classroom的students集合 */ 
  28.         Object firstStudent = Ognl.getValue('students[0]', context, context.getRoot());  
  29.         System.out.println('first student is : ' + firstStudent);  
  30.  
  31.         /* 調(diào)用集合的方法 */ 
  32.         Object size = Ognl.getValue('students.size()', context, context.getRoot());  
  33.         System.out.println('students collection size is :' + size);  
  34.  
  35.         System.out.println('--------------------------飄逸的分割線--------------------------');  
  36.           
  37.         Object mapCollection = Ognl.getValue('#student.contactWays', context, context.getRoot());  
  38.         System.out.println('mapCollection is :' + mapCollection);  
  39.  
  40.         Object firstElement = Ognl.getValue('#student.contactWays['homeNumber']', context, context.getRoot());  
  41.         System.out.println('the first element of contactWays is :' + firstElement);  
  42.  
  43.         System.out.println('--------------------------飄逸的分割線--------------------------');  
  44.  
  45.         /* 創(chuàng)建集合 */ 
  46.         Object createCollection = Ognl.getValue('{'aa','bb','cc','dd'}', context, context.getRoot());  
  47.         System.out.println(createCollection);  
  48.  
  49.         /* 創(chuàng)建Map集合 */ 
  50.         Object createMapCollection = Ognl.getValue('#{'key1':'value1','key2':'value2'}', context, context.getRoot());  
  51.         System.out.println(createMapCollection);  
  52.  
  53.     }  
  54. }  
  55.  
  56. class Classroom  
  57. {  
  58.     private List students = new ArrayList();  
  59.  
  60.     public List getStudents()  
  61.     {  
  62.         return students;  
  63.     }  
  64.  
  65.     public void setStudents(List students)  
  66.     {  
  67.         this.students = students;  
  68.     }  
  69. }  
  70.  
  71. class Student  
  72. {  
  73.     private Map contactWays = new HashMap();  
  74.  
  75.     public Map getContactWays()  
  76.     {  
  77.         return contactWays;  
  78.     }  
  79.  
  80.     public void setContactWays(Map contactWays)  
  81.     {  
  82.         this.contactWays = contactWays;  
  83.     }  

控制臺(tái)的輸出:

  1. students collection is :[zhangsan, lisi, wangwu, zhaoliu, qianqi]  
  2. first student is : zhangsan  
  3. students collection size is :5 
  4. --------------------------飄逸的分割線--------------------------  
  5. mapCollection is :{homeNumber=110, mobilePhone=112, companyNumber=119}  
  6. the first element of contactWays is :110 
  7. --------------------------飄逸的分割線--------------------------  
  8. [aa, bb, cc, dd]  
  9. {key1=value1, key2=value2} 

OGNL不僅可以操作集合對(duì)象,還可以創(chuàng)建集合對(duì)象,對(duì)集合操作與對(duì)屬性的操作沒什么不同,需要注意的是OGNL認(rèn)為L(zhǎng)ist與Array是一樣的。使用OGNL創(chuàng)建List集合時(shí)使用{},創(chuàng)建Map對(duì)象時(shí)使用#{}。

示例:使用OGNL過濾集合與投影集合

  1. public class OGNL4  
  2. {  
  3.     public static void main(String[] args) throws Exception  
  4.     {  
  5.         OgnlContext context = new OgnlContext();  
  6.  
  7.         Humen humen = new Humen();  
  8.         humen.setName('qiuyi');  
  9.         humen.setSex('n');  
  10.         humen.setAge(22);  
  11.         humen.getFriends().add(new Humen('zhangsan' , 'n' , 22));  
  12.         humen.getFriends().add(new Humen('lisi' , 'f' , 21));  
  13.         humen.getFriends().add(new Humen('wangwu' , 'n' , 23));  
  14.         humen.getFriends().add(new Humen('zhaoliu' , 'n' , 22));  
  15.         humen.getFriends().add(new Humen('qianqi' , 'n' , 22));  
  16.         humen.getFriends().add(new Humen('sunba' , 'f' , 20));  
  17.         humen.getFriends().add(new Humen('yangqiu' , 'f' , 25));  
  18.           
  19.         context.put('humen', humen);  
  20.         context.setRoot(humen);  
  21.  
  22.         /* OGNL過濾集合的語法為:collection.{? expression} */ 
  23.         Object filterCollection = Ognl.getValue('friends.{? #this.name.length() > 7}', context, context.getRoot());  
  24.         System.out.println('filterCollection is :' + filterCollection);  
  25.  
  26.         System.out.println('--------------------------飄逸的分割線--------------------------');  
  27.  
  28.         /* OGNL投影集合的語法為:collection.{expression} */ 
  29.         Object projectionCollection = Ognl.getValue('friends.{name}', context, context.getRoot());  
  30.         System.out.println('projectionCollection is :' + projectionCollection);  
  31.     }  
  32. }  
  33.  
  34. class Humen  
  35. {  
  36.     private String name;  
  37.     private String sex;  
  38.     private int age;  
  39.     private List friends = new ArrayList();  
  40.  
  41.     public Humen()  
  42.     {  
  43.  
  44.     }  
  45.  
  46.     public Humen(String name , String sex , int age)  
  47.     {  
  48.         this.name = name;  
  49.         this.sex = sex;  
  50.         this.age = age;  
  51.     }  
  52.  
  53.     public String getName()  
  54.     {  
  55.         return name;  
  56.     }  
  57.  
  58.     public void setName(String name)  
  59.     {  
  60.         this.name = name;  
  61.     }  
  62.  
  63.     public String getSex()  
  64.     {  
  65.         return sex;  
  66.     }  
  67.  
  68.     public void setSex(String sex)  
  69.     {  
  70.         this.sex = sex;  
  71.     }  
  72.  
  73.     public int getAge()  
  74.     {  
  75.         return age;  
  76.     }  
  77.  
  78.     public void setAge(int age)  
  79.     {  
  80.         this.age = age;  
  81.     }  
  82.  
  83.     public List getFriends()  
  84.     {  
  85.         return friends;  
  86.     }  
  87.  
  88.     public void setFriends(List friends)  
  89.     {  
  90.         this.friends = friends;  
  91.     }  
  92.  
  93.     @Override 
  94.     public String toString()  
  95.     {  
  96.         return 'Humen [name=' + name + ', sex=' + sex + ', age=' + age + ']';  
  97.     }  

控制臺(tái)輸出:

  1. filterCollection is :[Humen [name=zhangsan, sex=n, age=22]]  
  2. --------------------------飄逸的分割線--------------------------  
  3. projectionCollection is :[zhangsan, lisi, wangwu, zhaoliu, qianqi, sunba, yangqiu] 

OGNL可以對(duì)集合進(jìn)行過濾與投影操作,過濾的語法為collection.{? expression},其中使用'#this'表示集合當(dāng)前對(duì)象(可以與for-each循環(huán)比較)。投影的語法為collection.{expression}。投影和過濾可以看做是數(shù)據(jù)庫(kù)中對(duì)表取列和取行的操作。


Struts2與OGNL

Struts 2支持以下幾種表達(dá)式語言:
1. OGNL(Object-Graph Navigation Language),可以方便地操作對(duì)象屬性的開源表達(dá)式語言;
2. JSTL(JSP Standard Tag Library),JSP 2.0集成的標(biāo)準(zhǔn)的表達(dá)式語言;
3. Groovy,基于Java平臺(tái)的動(dòng)態(tài)語言,它具有時(shí)下比較流行的動(dòng)態(tài)語言(如Python、Ruby和Smarttalk等)的一些起特性;
4. Velocity,嚴(yán)格來說不是表達(dá)式語言,它是一種基于Java的模板匹配引擎,具說其性能要比JSP好。


Struts 2默認(rèn)的表達(dá)式語言是OGNL,原因是它相對(duì)其它表達(dá)式語言具有下面幾大優(yōu)勢(shì):
1. 支持對(duì)象方法調(diào)用,如xxx.doSomeSpecial();
2. 支持類靜態(tài)的方法調(diào)用和值訪問,表達(dá)式的格式為@[類全名(包括包路徑)]@[方法名 | 值名],例如:@java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME;
3. 支持賦值操作和表達(dá)式串聯(lián),如price=100, discount=0.8, calculatePrice(),這個(gè)表達(dá)式會(huì)返回80;
4. 訪問OGNL上下文(OGNL context)和ActionContext;
5. 操作集合對(duì)象。


——————————————以上內(nèi)容引用自http://www./max/archive/2007/04/28/114417.html

 

平時(shí)使用Struts2標(biāo)簽時(shí)會(huì)出現(xiàn)一些很奇特的問題,對(duì)于OGNL不了解的人可能對(duì)問題的出現(xiàn)無能為力或者就算解決了問題也不知道是如何解決的。下面總結(jié)一些使用Struts2標(biāo)簽容易出現(xiàn)的困惑:

問題一:#,%{},$符號(hào)

  在Struts2標(biāo)簽屬性中經(jīng)常會(huì)出現(xiàn)'#'或者'%{}'的符號(hào)出現(xiàn),通過上面OGNL表達(dá)式基礎(chǔ)的介紹,知道了OGNL上下文中有且僅有一個(gè)根對(duì)象。Struts2為我們定義了許多明明對(duì)象,他們分別是'ValueStack','Parameters','Session','Request', 'Appliction','Attr',其中'ValueStack'被設(shè)置為上下文的根對(duì)象。訪問非根對(duì)象必須加上'#'號(hào),這就是出現(xiàn)'#'的原因。Struts2中的標(biāo)的處理類,并不是所有都將標(biāo)簽的屬性作為OGNL表達(dá)式來看待,有時(shí)候我們需要設(shè)置動(dòng)態(tài)地值,則必須告訴標(biāo)簽的處理類該字符串按照OGNL表達(dá)式來處理,%{}符號(hào)的作用就是告訴標(biāo)簽的處理類將它包含的字符串按照OGNL表達(dá)式處理。 '$'符號(hào)用于XML文件中用于獲取動(dòng)態(tài)值,與%{}作用類似。

問題二:%{}符號(hào)的影響

  Struts2的標(biāo)簽幾十幾百個(gè),要記住哪一個(gè)標(biāo)簽的處理類將標(biāo)簽的屬性作為OGNL表達(dá)式是一件很困難的事情,在不清楚處理類的處理方式時(shí)怎么辦,%{}對(duì)于標(biāo)簽處理類來說,若處理類將屬性值作為普通字符串則%{}符號(hào)包含的字符串當(dāng)做OGNL表達(dá)式,若處理類將屬性值作為OGNL表達(dá)式來處理,則直接忽略%{}符號(hào)。換句話說,不清楚處理方式的話,可以都使用%{}符號(hào)。

問題三:標(biāo)簽是如何獲得數(shù)據(jù)

下面是ValueStack的官方描述:

ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending on the expression being evaluated).

大致意思:ValueStack允許保存多個(gè)bean(也就是Action),并且可以使用表達(dá)式語言獲得他們。當(dāng)評(píng)估一個(gè)表達(dá)式,ValueStack將會(huì)從棧頂?shù)綏5椎姆较虮凰阉饕槐?,?duì)于給定的屬性名稱尋找bean的getter或setter方法或?qū)ふ医o定的方法。

每當(dāng)一個(gè)請(qǐng)求到達(dá)Action時(shí),Struts2會(huì)將Action對(duì)象推入ValueStack中。

  1.    
  2.     username:<>'username'/>  
  3.     -------------------詭異的分割線-------------------  
  4.     username:<%= ((HelloWorldAction)ActionContext.getContext().getValueStack().peek()).getUsername() %>  
  5.    

頁(yè)面顯示結(jié)果:

  1. username:zhangsan  
  2. -------------------詭異的分割線-------------------  
  3. username:zhangsan 

可以看到標(biāo)簽取值與用Java代碼取值的結(jié)果相同,明顯標(biāo)簽的取值方式更簡(jiǎn)練簡(jiǎn)潔。OGNL表達(dá)式'username'表示了從根對(duì)象ValueStack中取出屬性u(píng)sername的值。它會(huì)從棧頂?shù)綏5妆闅vValueStack,直到找某一個(gè)Action中的'username'屬性。

個(gè)人學(xué)習(xí)心得,難免有錯(cuò)誤遺漏,歡迎指正討論!

原文鏈接:http://www.cnblogs.com/beliefbetrayal/archive/2012/02/11/2347244.html

【編輯推薦】

  1. 如何在Oracle中使用Java存儲(chǔ)過程(詳解)
  2. 郵件功能開發(fā):JavaMail
  3. 關(guān)于讀寫鎖算法的Java實(shí)現(xiàn)及思考
  4. 6個(gè)提高Java開發(fā)者效率的工具
  5. Java并發(fā):juc Executor框架詳解
【責(zé)任編輯:小林 TEL:(010)68476606】

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日本少妇三级三级三级| 婷婷色国产精品视频一区| 国产成人亚洲综合色就色| 九九热这里有精品20| 国产午夜精品久久福利| 亚洲中文字幕在线综合视频| 国产一区二区精品高清免费 | 免费特黄一级一区二区三区| 少妇人妻一级片一区二区三区| 午夜精品久久久99热连载| 久久99青青精品免费| 中文字幕91在线观看| 国产精品一区二区传媒蜜臀| 91亚洲熟女少妇在线观看| 后入美臀少妇一区二区| 日韩丝袜诱惑一区二区| 欧美三级大黄片免费看| 欧美一区二区不卡专区| 日本本亚洲三级在线播放| 91福利视频日本免费看看| 精品香蕉国产一区二区三区| 亚洲午夜精品视频在线| 五月婷婷欧美中文字幕| 欧美日韩黑人免费观看| 亚洲男人的天堂色偷偷| 狠色婷婷久久一区二区三区| 国产精品欧美一级免费| 精品人妻一区二区四区| 国产又大又黄又粗又免费| 日韩精品一区二区亚洲| 亚洲欧洲日韩综合二区| 91人妻人澡人人爽人人精品| 一区二区三区亚洲天堂| 一级片黄色一区二区三区| 午夜福利国产精品不卡| 国产丝袜美女诱惑一区二区| 日本在线视频播放91| 欧美黑人在线一区二区| 亚洲精品福利入口在线| 日本少妇三级三级三级| 狠狠亚洲丁香综合久久|