??xml version="1.0" encoding="utf-8" standalone="yes"?>精品国产青草久久久久福利,青青草原综合久久大伊人导航 ,国产精品美女久久久网AVhttp://www.shnenglu.com/wmuu/category/1631.html含笑半步癫是用蜂蜜、川贝、桔梗、加上天山雪莲配制而成Q不需冯Q也没有防腐剂,除了(jin)毒性猛烈之外,味道q很好吃Q而吃?jin)含W半步癫的朋友,֐思义l对不能走半步\或是面露W容Q否则也?x)全w爆炸而死。实在是居家旅行Q杀人灭口,必备良药Q? zh-cnWed, 21 May 2008 16:40:46 GMTWed, 21 May 2008 16:40:46 GMT60jni试用资料http://www.shnenglu.com/wmuu/archive/2008/01/05/40462.html含笑半步?/dc:creator>含笑半步?/author>Sat, 05 Jan 2008 08:17:00 GMThttp://www.shnenglu.com/wmuu/archive/2008/01/05/40462.htmlhttp://www.shnenglu.com/wmuu/comments/40462.htmlhttp://www.shnenglu.com/wmuu/archive/2008/01/05/40462.html#Feedback0http://www.shnenglu.com/wmuu/comments/commentRss/40462.htmlhttp://www.shnenglu.com/wmuu/services/trackbacks/40462.html

~译HelloWorldc?br>
 1 public class HelloWorld {
 2     public native void displayHelloWorld();
 3 
 4     public native void printxx(String str);
 5 
 6     static {
 7         System.loadLibrary("hello");
 8         // System.load("hello");
 9     }
10 
11     public static void main(String[] args) {
12         HelloWorld hw = new HelloWorld();
13         hw.displayHelloWorld();
14         for (int i = 0;; ++i) {
15             hw
16                     .printxx("wo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kao");
17             if (i % 1000 == 0) {
18                 try {
19                     Thread.sleep(10);
20                 } catch (InterruptedException e) {
21                 }
22             }
23         }
24     }
25 }

对编译完的class执行
javah HelloWorld

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class HelloWorld */
 4 
 5 #ifndef _Included_HelloWorld
 6 #define _Included_HelloWorld
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     HelloWorld
12  * Method:    displayHelloWorld
13  * Signature: ()V
14  */
15 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
16   (JNIEnv *, jobject);
17 
18 /*
19  * Class:     HelloWorld
20  * Method:    printxx
21  * Signature: (Ljava/lang/String;)V
22  */
23 JNIEXPORT void JNICALL Java_HelloWorld_printxx
24   (JNIEnv *, jobject, jstring);
25 
26 #ifdef __cplusplus
27 }
28 #endif
29 #endif
30 

~译
cl -I%java_home%\include -I%java_home%\include\win32 -LDHelloWorld.c -Fehello.dll

 1 #include <jni.h>
 2 #include "HelloWorld.h"
 3 #include <stdio.h>
 4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
 5 {
 6 printf("Hello world!\n"); 
 7 return;
 8 }
 9 
10 JNIEXPORT void JNICALL Java_HelloWorld_printxx
11   (JNIEnv *env, jobject obj, jstring prompt){
12 
13 const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
14   printf("%s",prompt);
15 (*env)->ReleaseStringUTFChars(env, prompt, str);
16   
17   return;
18   }
19   
20   




3QJavacd和本地类型对?br>  
  在如下情况下Q需要在本地Ҏ(gu)中应用java对象的引用,׃(x)用到cd之间的{换:(x)
  
  1QjavaҎ(gu)里面参C入本地方法;
  
  2Q在本地Ҏ(gu)里面创徏java对象Q?br>  
  3Q在本地Ҏ(gu)里面returnl果ljavaE序?br>  
  分ؓ(f)如下两种情况Q?br>  
  Java原始cd
  
  像booleans、integers、floats{从JavaE序中传到本地方法中的原始类型可以直接用,下面是java中的原始cd和本地方法中的类型的对应Q?br>  
  Javacd  本地cd  字节(bit)
  
  boolean   jboolean   8, unsigned
  byte    jbyte    8
  char    jchar    16, unsigned
  short    jshort    16
  int     jint     32
  long    jlong    64
  float    jfloat    32
  double   jdouble   64
  void    void     n/a
  
  也就是说如果我在Ҏ(gu)中传q去?jin)一个boolean的参数的话,那么我在本地Ҏ(gu)中就有jbooleancd与之对应。同理,如果在本地方法中return一个jint的话Q那么在java中就q回一个intcd?中国|管论坛
  
  Java对象
  
  Java对象做ؓ(f)引用被传递到本地Ҏ(gu)中,所有这些Java对象的引用都有一个共同的父类型jobject(相当于java中的ObjectcL所有类的父cM?。下面是JNI实现的一些jobject的子c:(x)
  
  4Q本地方法中讉KjavaE序中的内容
  
  1)讉KString对象Q?br>  
  从javaE序中传q去的String对象在本地方法中对应的是jstringcdQjstringcd和c中的char*不同Q所以如果你直接当做char*使用的话Q就?x)出错。因此在使用之前需要将jstring转换成ؓ(f)c/c++中的char*Q这里用JNIEnv的方法{换。下面是一个例子:(x)
  
  代码3Q?br>  
  JNIEXPORT jstring JNICALL Java_Prompt_getLine
  (JNIEnv *env, jobject obj, jstring prompt)
  {
  char buf[128];
  const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
  printf("%s", str);
  (*env)->ReleaseStringUTFChars(env, prompt, str);
  
  q里使用GetStringUTFCharsҎ(gu)传q来的promptQjstringcdQ{换成为UTFQ?的格式,p够在本地Ҏ(gu)中用了(jin)?br>  
  注意Q在使用完你所转换之后的对象之后,需要显C用ReleaseStringUTFCharsҎ(gu)Q让JVM释放转换成UTF-8的string的对象的I间Q如果不昄的调用的话,JVM中会(x)一直保存该对象Q不?x)被垃圾回收器回Ӟ因此׃?x)D内存溢出?

www.bitsCN.com


  
  下面是访问String的一些方法:(x)
  
  ◆GetStringUTFCharsjstring转换成ؓ(f)UTF-8格式的char*
  
  ◆GetStringCharsjstring转换成ؓ(f)Unicode格式的char*
  
  ◆ReleaseStringUTFChars释放指向UTF-8格式的char*的指?br>  
  ◆ReleaseStringChars释放指向Unicode格式的char*的指?br>  
  ◆NewStringUTF创徏一个UTF-8格式的String对象
  
  ◆NewString创徏一个Unicode格式的String对象
  
  ◆GetStringUTFLengt获取UTF-8格式的char*的长?br>  
  ◆GetStringLength获取Unicode格式的char*的长?br>  
  2) 讉KArray对象Q?br>  
  和String对象一P在本地方法中不能直接讉Kjarray对象Q而是使用JNIEnv指针指向的一些方法来是用?br>  
  讉KJava原始cd数组Q?br>  
  1Q获取数l的长度Q?br>  
  代码4Q?br>  
  JNIEXPORT jint JNICALL Java_IntArray_sumArray
  (JNIEnv *env, jobject obj, jintArray arr)
  {
  int i, sum = 0;
  jsize len = (*env)->GetArrayLength(env, arr);
  
  如代?所C,q里获取数组的长度和普通的c语言中的获取数组长度不一Pq里使用JNIEvn的一个函数GetArrayLength?
bitsCN_com

  
  2Q获取一个指向数l元素的指针Q?br>  
  代码4Q?br>  
  jint *body = (*env)->GetIntArrayElements(env, arr, 0);
  
  使用GetIntArrayElementsҎ(gu)获取指向arr数组元素的指针,注意该函数的参数Q第一个是JNIEnvQ第二个是数l,W三个是数组里面W三个是数组里面开始的元素
  
  3Q用指针取出Array中的元素
  
  代码5Q?br>  
  for (i=0; i<len; i++) {
  sum += body[i];
  }
  
  q里使用和普通的c中的数组使用没有什么不同了(jin)
  
  4Q释放数l元素的引用
  
  代码6Q?br>  
  (*env)->ReleaseIntArrayElements(env, arr, body, 0);
  
  和操作String中的释放String的引用是一L(fng)Q提醒JVM回收arr数组元素的引用?br>  
  q里丄例子是用int数组的,同样q有boolean、float{对应的数组?br>  
  获取数组元素指针的对应关p:(x)
  
  函数            数组cd
  
  GetBooleanArrayElements   boolean
  GetByteArrayElements    byte
  GetCharArrayElements    char bitsCN.nET中国|管博客
  GetShortArrayElements    short
  GetIntArrayElements     int
  GetLongArrayElements    long
  GetFloatArrayElements    float
  GetDoubleArrayElements   double
  
  释放数组元素指针的对应关p:(x)
  Function            Array Type
  ReleaseBooleanArrayElements   boolean
  ReleaseByteArrayElements    byte
  ReleaseCharArrayElements    char
  ReleaseShortArrayElements    short
  ReleaseIntArrayElements     int
  ReleaseLongArrayElements    long
  ReleaseFloatArrayElements    float
  ReleaseDoubleArrayElements   double
  
  讉K自定义Java对象数组
  
  The JNI provides a separate set of functions to access elements of object arrays. You can use these functions to get and set individual object array elements.
  
  Note: You cannot get all the object array elements at once.
  
  GetObjectArrayElement returns the object element at a given index.
www_bitscn_com

  
  SetObjectArrayElement updates the object element at a given index.
  
  3) 讉KJava对象的方法:(x)
  
  在本地方法中调用Java对象的方法的步骤Q?br>  
  ?获取你需要访问的Java对象的类Q?br>  
  jclass cls = (*env)->GetObjectClass(env, obj);
  
  使用GetObjectClassҎ(gu)获取obj对应的jclass?br>  
  ?获取MethodIDQ?br>  
  jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
  
  使用GetMethdoIDҎ(gu)获取你要使用的方法的MethdoID。其参数的意义:(x)
  
  env??>JNIEnv
  
  cls??>W一步获取的jclass
  
  "callback"??>要调用的Ҏ(gu)?br>  
  "(I)V"??>Ҏ(gu)的Signature
  
  ?调用Ҏ(gu)Q?br>  
  (*env)->CallVoidMethod(env, obj, mid, depth);
  
  使用CallVoidMethodҎ(gu)调用Ҏ(gu)。参数的意义Q?br>  
  env??>JNIEnv
  
  obj??>通过本地Ҏ(gu)I过来的jobject
  
  mid??>要调用的MethodIDQ即W二步获得的MethodIDQ?br>  
  depth??>Ҏ(gu)需要的参数Q对应方法的需求,d相应的参敎ͼ(j) bitsCN.nET中国|管博客
  
  注:(x)q里使用的是CallVoidMethodҎ(gu)调用Q因为没有返回|如果有返回值的话用对应的Ҏ(gu)Q在后面?x)提到?br>  
  Ҏ(gu)的Signature
  
  Ҏ(gu)的Signature是由Ҏ(gu)的参数和q回值的cd共同构成的,下面是他们的l构Q?br>  
  "(argument-types)return-type"
  
  其中JavaE序中参数类型和其对应的值如下:(x)
  
  Signature  Java中的cd
  Z       boolean
  B       byte
  C       char
  S       short
  I       int
  J       long
  F       float
  D       double
  L fully-qualified-class;   fully-qualified-class
  
  [ type  type[]
  
  ( arg-types ) ret-type  method type
  
  一个JavacȝҎ(gu)的Signature可以通过javap命o(h)获取Q?br>  
  javap -s -p Javacd
  
  l调用的函数传参敎ͼ(x)
  
  通常我们直接在methodID后面要传的参数d在后面,但是q有其他的方法也可以传参敎ͼ(x)
  
  CallVoidMethodV可以获取一个数量可变的列表作ؓ(f)参数Q?www_bitscn_com
  
  CallVoidMethodA可以获取一个union?br>  
  调用?rn)态方法:(x)
  
  是第二步和第三步调用的方法改为对应的Q?br>  
  GetStaticMethodID获取对应的静(rn)态方法的ID
  
  CallStaticIntMethod调用?rn)态方?br>  
  调用类的方法:(x)
  
  用的比较?yu),自己看啦。^_^?br>  
  4)讉KJava对象的属性:(x)
  
  讉KJava对象的属性和讉KJava对象的方法基本上一P只需要将函数里面的Method改ؓ(f)Field卛_







]]>
java classpath 扚w讄脚本http://www.shnenglu.com/wmuu/archive/2008/01/04/40401.html含笑半步?/dc:creator>含笑半步?/author>Fri, 04 Jan 2008 07:45:00 GMThttp://www.shnenglu.com/wmuu/archive/2008/01/04/40401.htmlhttp://www.shnenglu.com/wmuu/comments/40401.htmlhttp://www.shnenglu.com/wmuu/archive/2008/01/04/40401.html#Feedback0http://www.shnenglu.com/wmuu/comments/commentRss/40401.htmlhttp://www.shnenglu.com/wmuu/services/trackbacks/40401.html

YOUR_LIB=your_path

for jar in `ls $YOUR_LIB/*.jar`
do
      CLASSPATH="$CLASSPATH:""$jar"
done


windows :


SETLOCAL ENABLEDELAYEDEXPANSION
set LIB=xx
set CLASSPATH=.
FOR %%C IN (LIB\*.jar) DO set CLASSPATH=!CLASSPATH!;%%C
echo %CLASSPATH%



unix ksh:
暂无



]]>
java中Double-Checked Locking 双重锁定的测试代?/title><link>http://www.shnenglu.com/wmuu/archive/2007/01/19/17782.html</link><dc:creator>含笑半步?/dc:creator><author>含笑半步?/author><pubDate>Fri, 19 Jan 2007 06:59:00 GMT</pubDate><guid>http://www.shnenglu.com/wmuu/archive/2007/01/19/17782.html</guid><wfw:comment>http://www.shnenglu.com/wmuu/comments/17782.html</wfw:comment><comments>http://www.shnenglu.com/wmuu/archive/2007/01/19/17782.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/wmuu/comments/commentRss/17782.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/wmuu/services/trackbacks/17782.html</trackback:ping><description><![CDATA[ <p> <br /> (tng)</p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"> <span style="COLOR: #008080"> (tng)1</span> (tng)<span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> (tng)test;<br /></span><span style="COLOR: #008080"> (tng)2</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> (tng)3</span> (tng)<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> (tng)testClone (tng){<br /></span><span style="COLOR: #008080"> (tng)4</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">boolean</span><span style="COLOR: #000000"> (tng)isInit;<br /></span><span style="COLOR: #008080"> (tng)5</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> (tng)6</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000"> (tng)Foo (tng)foo;<br /></span><span style="COLOR: #008080"> (tng)7</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> (tng)8</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> (tng)time (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080"> (tng)9</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">10</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> (tng)Foo (tng){<br /></span><span style="COLOR: #008080">11</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> (tng)flg;<br /></span><span style="COLOR: #008080">12</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">13</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)Foo() (tng){<br /></span><span style="COLOR: #008080">14</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)flg (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">15</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> (tng){<br /></span><span style="COLOR: #008080">16</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Thread.sleep(time);<br /></span><span style="COLOR: #008080">17</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (tng)(InterruptedException (tng)e) (tng){<br /></span><span style="COLOR: #008080">18</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">19</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">flg;<br /></span><span style="COLOR: #008080">20</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Foo (tng)inited</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">21</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">22</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">23</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">24</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> (tng)main(String[] (tng)args) (tng)</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> (tng)I(yng)nterruptedException (tng){<br /></span><span style="COLOR: #008080">25</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)testClone (tng)t (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> (tng)testClone();<br /></span><span style="COLOR: #008080">26</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)t.test();<br /></span><span style="COLOR: #008080">27</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">28</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">29</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> (tng)test() (tng){<br /></span><span style="COLOR: #008080">30</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (tng)(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> (tng)i (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; (tng)i (tng)</span><span style="COLOR: #000000"><</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">; (tng)</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i) (tng){<br /></span><span style="COLOR: #008080">31</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)WorkThread (tng)t (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> (tng)WorkThread();<br /></span><span style="COLOR: #008080">32</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)t.start();<br /></span><span style="COLOR: #008080">33</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">34</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">35</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (tng)(;;) (tng){<br /></span><span style="COLOR: #008080">36</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> (tng){<br /></span><span style="COLOR: #008080">37</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Thread.sleep(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">38</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (tng)(InterruptedException (tng)e) (tng){<br /></span><span style="COLOR: #008080">39</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">40</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)time (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">41</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000"> (tng)(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">) (tng){<br /></span><span style="COLOR: #008080">42</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)foo (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">43</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">44</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">45</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">46</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">47</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)Foo (tng)bar() (tng){<br /></span><span style="COLOR: #008080">48</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Foo (tng)f (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)foo;<br /></span><span style="COLOR: #008080">49</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (tng)(f (tng)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) (tng){<br /></span><span style="COLOR: #008080">50</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000"> (tng)(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">) (tng){<br /></span><span style="COLOR: #008080">51</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (tng)(foo (tng)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) (tng){<br /></span><span style="COLOR: #008080">52</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)foo (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> (tng)Foo();<br /></span><span style="COLOR: #008080">53</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">54</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (tng)foo;<br /></span><span style="COLOR: #008080">55</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">56</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">57</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (tng)f;<br /></span><span style="COLOR: #008080">58</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">59</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">60</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> (tng)WorkThread (tng)</span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> (tng)Thread (tng){<br /></span><span style="COLOR: #008080">61</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> (tng)run() (tng){<br /></span><span style="COLOR: #008080">62</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (tng)(;;) (tng){<br /></span><span style="COLOR: #008080">63</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> (tng){<br /></span><span style="COLOR: #008080">64</span> (tng)<span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">65</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Foo (tng)f (tng)</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (tng)bar();<br /></span><span style="COLOR: #008080">66</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (tng)(f.flg (tng)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (tng)</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">) (tng){<br /></span><span style="COLOR: #008080">67</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(f.flg);<br /></span><span style="COLOR: #008080">68</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">69</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (tng)(Throwable (tng)e) (tng){<br /></span><span style="COLOR: #008080">70</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)e.printStackTrace();<br /></span><span style="COLOR: #008080">71</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">72</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">73</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">74</span> (tng)<span style="COLOR: #000000"> (tng) (tng) (tng) (tng)}<br /></span><span style="COLOR: #008080">75</span> (tng)<span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">76</span> (tng)<span style="COLOR: #000000"></span></div> <p> <br /> <br />1.4.2jdk~译执行。长旉执行没有发现有网上所说的׃jit优化D的当分配完Foo的内存,Foo构造函数未初始化完成就其地址赋值给foo的错误。相信这时候jit已经对代码进行了(jin)优化?br /><br />国外|址关于Double-Checked Locking的文?a >http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html</a></p> <h4>A test case showing that it doesn't work</h4> <p>Paul Jakubik found an example of a use of double-checked locking that did not work correctly. <a >A slightly cleaned up version of that code is available here</a>. </p> <p>When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles </p> <center> <pre>singletons[i].reference = new Singleton();</pre> </center> <p>to the following (note that the Symantec JIT using a handle-based object allocation system). </p> <pre>0206106A mov eax,0F97E78h 0206106F call 01F6B210 ; allocate space for ; Singleton, return result in eax 02061074 mov dword ptr [ebp],eax ; EBP is &singletons[i].reference ; store the unconstructed object here. 02061077 mov ecx,dword ptr [eax] ; dereference the handle to ; get the raw pointer 02061079 mov dword ptr [ecx],100h ; Next 4 lines are 0206107F mov dword ptr [ecx+4],200h ; Singleton's inlined constructor 02061086 mov dword ptr [ecx+8],400h 0206108D mov dword ptr [ecx+0Ch],0F84030h </pre> <p>As you can see, the assignment to <tt>singletons[i].reference</tt> is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model). <br />上面是国外网站给出的jit代码和说明?br /><br /><br /></p> <img src ="http://www.shnenglu.com/wmuu/aggbug/17782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/wmuu/" target="_blank">含笑半步?/a> 2007-01-19 14:59 <a href="http://www.shnenglu.com/wmuu/archive/2007/01/19/17782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>试用java1.5Qؕ?/title><link>http://www.shnenglu.com/wmuu/archive/2006/07/19/10208.html</link><dc:creator>含笑半步?/dc:creator><author>含笑半步?/author><pubDate>Wed, 19 Jul 2006 02:19:00 GMT</pubDate><guid>http://www.shnenglu.com/wmuu/archive/2006/07/19/10208.html</guid><wfw:comment>http://www.shnenglu.com/wmuu/comments/10208.html</wfw:comment><comments>http://www.shnenglu.com/wmuu/archive/2006/07/19/10208.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/wmuu/comments/commentRss/10208.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/wmuu/services/trackbacks/10208.html</trackback:ping><description><![CDATA[java1.5出来很久?jin),最q才去试?jin)试。发?.5虽然说支持模板了(jin)Q但是像int q样的基cdq是不能支持Q只能支持类对象。而且不支持运符重蝲Q极大限制了(jin)模板的用。比起c++的模板,意义不是很大Q最大的好处是从容器里头取对象不用手工进行类型{换。看来先天不I后天q是不好补。无论sun如何努力Q始l无法掩盖设计上的失败?br />1.5在线E方面多?jin)线E池Q和一些其他功能,q是不错的。因为我刚好用的刎ͼ(x)Q。这让我惛_c++Q比起sun?qing)其W三方的java库的疯狂扩张Qc++的标准库让h感觉q于保守。java对一些实际上已经成ؓ(f)标准的东西的支持Q以?qing)c++对这些东西自生自灭的态度(虽然有boost库,但毕竟不是正式标?以及(qing)Ҏ(gu)准库的实现放任自q态度(没有一个标准的实现)Q难免让c++的支持者感C些失望?img src ="http://www.shnenglu.com/wmuu/aggbug/10208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/wmuu/" target="_blank">含笑半步?/a> 2006-07-19 10:19 <a href="http://www.shnenglu.com/wmuu/archive/2006/07/19/10208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>看文章《Java ~程的动态性》后的想?/title><link>http://www.shnenglu.com/wmuu/archive/2006/05/31/7992.html</link><dc:creator>含笑半步?/dc:creator><author>含笑半步?/author><pubDate>Wed, 31 May 2006 14:13:00 GMT</pubDate><guid>http://www.shnenglu.com/wmuu/archive/2006/05/31/7992.html</guid><wfw:comment>http://www.shnenglu.com/wmuu/comments/7992.html</wfw:comment><comments>http://www.shnenglu.com/wmuu/archive/2006/05/31/7992.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/wmuu/comments/commentRss/7992.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/wmuu/services/trackbacks/7992.html</trackback:ping><description><![CDATA[java里头反射很强Q但是要把一个函C递出ȝ很麻?ch)。sun把原先的枚Dcd成了(jin)q代器类Q?.5里头不甘愿的把泛形加?jin)进来。以后呢Q我惛_C?x)像c一样可以传递,说不定说有的东西都是对象Q函C是一U对象,可以自由传递?br />接着加了(jin)泛Ş的util包会(x)不会(x)来像stl呢?<br /><img src ="http://www.shnenglu.com/wmuu/aggbug/7992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/wmuu/" target="_blank">含笑半步?/a> 2006-05-31 22:13 <a href="http://www.shnenglu.com/wmuu/archive/2006/05/31/7992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学用BCEL设计字节码的记录(java)http://www.shnenglu.com/wmuu/archive/2006/05/31/7947.html含笑半步?/dc:creator>含笑半步?/author>Wed, 31 May 2006 08:44:00 GMThttp://www.shnenglu.com/wmuu/archive/2006/05/31/7947.htmlhttp://www.shnenglu.com/wmuu/comments/7947.htmlhttp://www.shnenglu.com/wmuu/archive/2006/05/31/7947.html#Feedback3http://www.shnenglu.com/wmuu/comments/commentRss/7947.htmlhttp://www.shnenglu.com/wmuu/services/trackbacks/7947.html最q看?span style="COLOR: #999999">Java ~程的动态性,W?7 部分: ?BCEL 设计字节码,|址?a >http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/

其中的示范代码解释的不是很详l,q方面的中文资料又少Q只好自p旉看下厅Rbcel的类库却是不够友好,api文档也是走马观花的点一下,很多函数没有说明。理解基本靠猜,q好有个C代码。下面对自己理解的东西做个记录,详细的代码可以到上面的链接下载?br />

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;

public class BCELTiming {
 (tng) (tng) (tng) /**
 (tng) (tng) (tng) (tng) * Add timing wrapper to method of class. The method can accept any
 (tng) (tng) (tng) (tng) * arguments and return any type (including void), but must be a normal
 (tng) (tng) (tng) (tng) * (non-static, non-initializer) method to be used with this code as
 (tng) (tng) (tng) (tng) * currently implemented. Handling the other types of methods would not
 (tng) (tng) (tng) (tng) * involve any fundamental changes to the code.
 (tng) (tng) (tng) (tng) *
 (tng) (tng) (tng) (tng) * @param cgen
 (tng) (tng) (tng) (tng) * (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) generator for class being modified
 (tng) (tng) (tng) (tng) * @param method
 (tng) (tng) (tng) (tng) * (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) current method to be enhanced with timing wrapper
 (tng) (tng) (tng) (tng) */

 (tng) (tng) (tng) private static void addWrapper(ClassGen cgen, Method method) {

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // set up the construction tools
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) InstructionFactory ifact = new InstructionFactory(cgen);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) InstructionList ilist = new InstructionList();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ConstantPoolGen pgen = cgen.getConstantPool();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String cname = cgen.getClassName();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) MethodGen wrapgen = new MethodGen(method, cname, pgen);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) wrapgen.setInstructionList(ilist);

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // rename a copy of the original method
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) MethodGen methgen = new MethodGen(method, cname, pgen);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) cgen.removeMethod(method);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String iname = methgen.getName() + "$impl";
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) methgen.setName(iname);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) cgen.addMethod(methgen.getMethod());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) //以上是一下初始化的工?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // compute the size of the calling parameters
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // operand stack操作数堆?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type[] types = methgen.getArgumentTypes(); // 取出参数cd数组

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // solt代表本地变量的堆栈偏U量,里头储存?sh)(jin)调用methen代表的函数的参数
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) int slot = methgen.isStatic() ? 0 : 1; // q种方式与Java如何处理Ҏ(gu)调用有关。对于非?rn)态的Ҏ(gu)Q每ơ调用的W一个(隐藏的)(j)参数是目标对象的this引用Q就是位|?储存的内容)(j)?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) for (int i = 0; i < types.length; i++) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) slot += types[i].getSize();// 累计个个参数cd的长度,
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // 现在solt指向最后一个参数的下一个位|?/p>

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // save time prior to invocation
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // 调用?rn)态的long java.lang.System.currentTimeMillis()Ҏ(gu),调用l束后函数的q回的longcd的g(x)压入operand stack操作数堆?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createInvoke("java.lang.System",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) "currentTimeMillis", Type.LONG, Type.NO_ARGS,
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Constants.INVOKESTATIC));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createStore(Type.LONG, slot));// operand stack的top保存到本地变量堆栈的slot位置,operand stack弹出long?/p>

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // call the wrapped method
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) int offset = 0; // 偏移?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) short invoke = Constants.INVOKESTATIC; // 预先讄用静(rn)态函?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (!methgen.isStatic()) { // 如果不是调用?rn)态函?调用的W一个(隐藏的)(j)参数(目标对象的this引用)压入operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) offset = 1;// 偏移量加1
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) invoke = Constants.INVOKEVIRTUAL;// 讄用非?rn)态函?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) for (int i = 0; i < types.length; i++) { // 遍历所有参?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type type = types[i];
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createLoad(type, offset)); // 按参数类型把参数一个个从本地变量堆栈取出,压入operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) offset += type.getSize();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type result = methgen.getReturnType();// 取得要调用函数的q回值类?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createInvoke(cname, iname, result, types, invoke));// 调用Ҏ(gu)名ؓ(f)iname的函?/p>

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // store result for return later
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (result != Type.VOID) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createStore(result, slot + 2)); // 名为iname的函数返回值复制到本地变量堆栈的slot+2的位|上
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // print time required for method call
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // 获取?rn)态对象java.lang.System.out的引?q回值压入operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createFieldAccess("java.lang.System", "out",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionConstants.DUP);// 取operand stack的top,压入operand stack。完成后load_stack的头两个元素是静(rn)态对象java.lang.System.out的引?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionConstants.DUP);// 取operand stack的top,压入operand stack。现在有3个java.lang.System.out的引用。供下面3ơ调用out.print()函数使用
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) String text = "Call to method " + methgen.getName() + " took ";
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(new PUSH(pgen, text));// text攑օpgenQ代表常量池Q?q把其在pgen的引用压入operand stack(供out.print(Sting)调用的参?
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type.VOID, new Type[] { Type.STRING },
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Constants.INVOKEVIRTUAL));// 调用l束Qoperand stack弹出一个String的引用和一个out的引?q剩2个out),函数没有q回?/p>

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createInvoke("java.lang.System",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) "currentTimeMillis", Type.LONG, Type.NO_ARGS,
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Constants.INVOKESTATIC));// 调用java.lang.System.currentTimeMillis()Ҏ(gu),调用l束后函数的q回的longcd的g(x)压入堆栈operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createLoad(Type.LONG, slot));// 从本地变量堆栈的slot位置载入先前储存的long|压入operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionConstants.LSUB);// 调用long的减法指?弹出2个long|q把l果压入operand stack,现在operand stack的topW一个是longQ第二个是out的引?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(ifact.createInvoke("java.io.PrintStream", "print",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type.VOID, new Type[] { Type.LONG }, Constants.INVOKEVIRTUAL));// 调用out.print(long)Ҏ(gu)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(new PUSH(pgen, " ms."));// String对象" ms."攑օpgen,q把其在pgen的引用压入operand stack(供out.print(Sting)调用的参?
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) .append(ifact.createInvoke("java.io.PrintStream", "println",
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Type.VOID, new Type[] { Type.STRING },
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Constants.INVOKEVIRTUAL));

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) // return result from wrapped method call
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (result != Type.VOID) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createLoad(result, slot + 2));// 处理q回?如果不ؓ(f)I,从本地对象堆栈的slot+2位置d指定cd的返回值压入operand stack
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.append(InstructionFactory.createReturn(result)); //调用处理q回值的指o(h)Qresult回值的cd

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) //下面是一下扫ַ?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) // finalize the constructed method
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) wrapgen.stripAttributes(true);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) wrapgen.setMaxStack();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) wrapgen.setMaxLocals();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) cgen.addMethod(wrapgen.getMethod());
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) ilist.dispose();
 (tng) (tng) (tng) }

 (tng) (tng) (tng) public static void main(String[] argv) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (argv.length == 2 && argv[0].endsWith(".class")) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) try {

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) JavaClass jclas = new ClassParser(argv[0]).parse();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ClassGen cgen = new ClassGen(jclas);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Method[] methods = jclas.getMethods();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) int index;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) for (index = 0; index < methods.length; index++) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (methods[index].getName().equals(argv[1])) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) break;
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) if (index < methods.length) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) addWrapper(cgen, methods[index]);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) FileOutputStream fos = new FileOutputStream(argv[0]);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) cgen.getJavaClass().dump(fos);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) fos.close();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) System.err.println("Method " + argv[1] + " not found in "
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) + argv[0]);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) } catch (IOException ex) {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ex.printStackTrace(System.err);
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) }

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) } else {
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) System.out.println("Usage: BCELTiming class-file method-name");
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) }
 (tng) (tng) (tng) }
}


相对javassistQbcel实比较复杂。但是bcell我的感觉比较自由,有种一切尽在掌握的感觉Q这一Ҏ(gu)较我喜欢?br />虽然自由Q但是用bcel写一个类的实现绝对不?x)是一件让人开?j)的事情Q如果碰巧你的实现又E微复杂?jin)?比如实现?jin)xx接口Q又增加?jin)一些函数和成员变量)。而且你的实现未必?x)比javac~译出来的代码效率高Q不考虑jvm的动态优化)(j)?br />不过Q先把你要实现的cȝ代码写出来,按照代码来写bcel的实玎ͼ?x)降低些实现隑ֺ?/p>

]]>
一下关于java动态代码生成的文章http://www.shnenglu.com/wmuu/archive/2006/05/28/7753.html含笑半步?/dc:creator>含笑半步?/author>Sat, 27 May 2006 19:05:00 GMThttp://www.shnenglu.com/wmuu/archive/2006/05/28/7753.htmlhttp://www.shnenglu.com/wmuu/comments/7753.htmlhttp://www.shnenglu.com/wmuu/archive/2006/05/28/7753.html#Feedback0http://www.shnenglu.com/wmuu/comments/commentRss/7753.htmlhttp://www.shnenglu.com/wmuu/services/trackbacks/7753.html http://www-128.ibm.com/developerworks/cn/java/j-cwt05125/  (tng) Classworking 工具? ASM classworking

http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/ (tng) Java ~程的动态性。这个系列中作者比较详l的介绍?jin)javassistQ粗略的提到?jin)bcel和asm?br />
作者是Dennis Sosnoski,看了(jin)?span style="COLOR: #999999">Java ~程的动态性的前六,感觉不错。因为国内这斚w的资料太了(jin)?/span>
q有是ibm上的文档实不错。虽然有的时间比较旧Q但是确实对于国内来说不可多得的中文文。当然新的文也不少?/span>


]]>
java里头居然q有SoftReference、WeakReference ?PhantomReferencehttp://www.shnenglu.com/wmuu/archive/2006/05/11/6918.html含笑半步?/dc:creator>含笑半步?/author>Thu, 11 May 2006 02:09:00 GMThttp://www.shnenglu.com/wmuu/archive/2006/05/11/6918.htmlhttp://www.shnenglu.com/wmuu/comments/6918.htmlhttp://www.shnenglu.com/wmuu/archive/2006/05/11/6918.html#Feedback4http://www.shnenglu.com/wmuu/comments/commentRss/6918.htmlhttp://www.shnenglu.com/wmuu/services/trackbacks/6918.html

]]>
ùƷӰ˾þ| þþƷ| þþƷרѶ| ˺ݺۺ88ۺϾþ| 99þþƷѿһ| պƷþĻ| ۺŮþþ30p| ޾þþþþ77777 ޾Ʒþþþϼ | ޾ƷƵþþ| þþƷ޾Ʒ| þþþþƷ66| AV˾þԭ| þþƷĻһ| ˳ɾƷþþþ| һֻƴƬ99þ| 7ŷպۺľþþþ| þþþþ| Ĺ˾Ʒþ޾ƷA뾫Ʒ | þֻоƷþ| þþþӰԺŮ| þþƷA㽶| ھƷ˾þþӰԺ| ޾Ʒþþþ| ŷƷ˾þ| ձɫվWWWþ| ޾Ʒþþþ| ھƷþþþþþcoent | þþþĻɫ| þþþþƷAV| þAVۺϺɫ| ˾Ʒһþ| ƷþþþaӰԺ| þþƷվ| ģ˽ĹƷþ| þۺ϶㼤þ| þþþþþþƷŮ99 | ƷȾþav| avԾþþþa鶹 | 99þĻ| ˾þô߽ۺվ| Ʒtvþþþþþ|