ASMSupport教程4.11 生成數組操做

<p>在任何語言裏,數組都是基本的數據類型,咱們這一節將講述如何生成數組操做。</p> <p>數組操做包括如下幾個:</p> <ol> <li>建立數組 </li> <li>獲取數組長度 </li> <li>獲取數組每一個元素的內容 </li> <li>爲數組元素賦值 </li> </ol> <p>咱們接下來對每種操做進行詳解。</p> <h3><font style="font-weight: bold">建立數組</font></h3> <hr /> <p>咱們知道在java中建立數有如下幾種方式:</p> <ol> <li>只爲數組的分配必定大小的空間,好比:int[][] i1 = new int[2][2]; </li> <li>若是是多維數組只爲部分維度分配空間,好比:int[][] i2 = new int[2][]; </li> <li>在建立數組的時候爲每一個元素賦值,好比:String[] s1 = { &quot;array \&quot;s1\&quot; first value&quot;, &quot;array \&quot;s1\&quot; second value&quot; }; </li> <li>這種方式和第三中方式差很少,只不過這裏建立的是多維數組,好比:String[][] s2 = { { &quot;s2[0][0]&quot;, &quot;s2[0][1]&quot; }, { &quot;s2[1][0]&quot;, &quot;s2[1][1]&quot; } }; </li> </ol> <p>那麼我麼如何使用ASMSupport建立上面的四種數組呢,咱們按照上面介紹的四種方式的順序來介紹。</p> <h4><font style="font-weight: bold">1.只爲數組的分配必定大小的空間,建立int[][] i1 = new int[2][2];</font></h4> <p>這種方式建立數組咱們須要使用的是以下方法:</p> <p><font color="#f79646"><strong>jw.asmsupport.block.ProgramBlock.newArray(final ArrayClass aClass, final Parameterized... allocateDims):</strong></font></p> <ul> <li><strong>參數:</strong> </li> </ul> <ol> <li>當前須要建立的數組值是什麼類型(類型是ArrayClass) </li> <li>爲其每個維分配的空間數, 這是個變元參數,爲何變元參數,在咱們用第二種方式建立數組的時候將會用到。 </li> </ol> <ul> <li><strong>返回類型:</strong> </li> </ul> <p>這個方法返回的是一個<font color="#f79646">jw.asmsupport.operators.array.ArrayValue</font>類型,這個類型就是表示一個數組。咱們看到第一個參數是<font color="#f79646">jw.asmsupport.clazz.ArrayClass</font>類型的, 咱們經過AClassFactory的getArrayClass方法獲取其對應的AClass.這裏介紹下getArrayClass的方法:</p> <p>getArrayClass有三個重載的方法:</p> <ol> <li><strong>getArrayClass(Class&lt;?&gt; arrayCls):</strong> 這裏的參數類型是一個Array的類型。好比咱們須要獲取一個int[]類型的ArrayClass,那麼咱們能夠經過getArrayClass(int[].class)獲取 </li> <li><strong>getArrayClass(Class&lt;?&gt; cls, int dim):</strong> 這裏的第一參數是一個任意類型的Class。第二個參數表示須要建立的ArrayClass的維數。經過這個方法獲得的將是一個以第一個參數爲基本類型,維數爲第二個參數的ArrayClass。好比:getArrayClass(int.class, 2)將獲得一個int[][]類型的ArrayClass;getArrayClass(int[].class, 2)將獲得一個int[][][]類型的ArrayClass。 </li> <li><strong>getArrayClass(AClass cls, int dim):</strong> 這個方法和上面那個方法相似,只是將第一個個參數類型變成了AClass。其餘相同這裏還能夠經過getProductClass(Class&lt;?&gt; cls)方法獲取ArrayClass,和 getArrayClass(Class&lt;?&gt; arrayCls)用法相同。只是返回類型是AClass。咱們能夠將其強制轉換成ArrayClass。 </li> </ol> <p>介紹了這麼多,那麼咱們就能夠用下面的代碼來生成字節碼內容:</p> <div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:205f032f-17f0-4789-b7cb-f32d502257b3" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 945px; height: 50px;" style=" width: 945px; height: 50px;overflow: auto;">ArrayValue av = newArray(AClassFactory.getArrayClass(int[][].class), Value.value(2), Value.value(2)); LocalVariable i1 = createArrayVariable(&quot;i1&quot;, AClassFactory.getArrayClass(int[][].class), false, av);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>java

<p>&#160;</p>web

<p>解釋下上面的代碼,首先經過newArray方法建立一個數組值av,再建立一個i1變量並將av賦值給i1再建立System.out.println(ArrayUtils.toString(i1)),下面是對應的生成的代碼:</p>apache

<p>&#160;</p>編程

<p><font style="font-weight: bold">2.若是是多維數組只爲部分維度分配空間,建立int[][] i2 = new int[2][];</font></p>數組

<p>這裏咱們用的方法和上面第一種方式的同樣,惟一不一樣的就是咱們的變元參數的傳遞,這裏咱們只須要傳遞第一個維度的值就能夠了,這也就是爲何須要用變元參數的緣由。代碼以下:</p>app

<div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:cb7ef075-df46-4f98-80be-1105831260a9" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 945px; height: 41px;" style=" width: 945px; height: 41px;overflow: auto;">av = newArray(AClassFactory.getArrayClass(int[][].class), Value.value(2)); LocalVariable i2 = createArrayVariable(&quot;i2&quot;, AClassFactory.getArrayClass(int[][].class), false, av);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>ide

<p><strong>3.在建立數組的時候爲每一個元素賦值,建立String[] s1 = { &quot;array \&quot;s1\&quot; first value&quot;, &quot;array \&quot;s1\&quot; second value&quot; };</strong></p>code

<p>這裏有五個方法能夠實現這種方式:</p>orm

<ol> <li><strong>public ArrayValue newArrayWithValue(final ArrayClass aClass, final Object arrayObject)</strong> </li>對象

<li><strong>public ArrayValue newArrayWithValue(final ArrayClass aClass, final Parameterized[] values)</strong> </li>

<li><strong>public ArrayValue newArrayWithValue(final ArrayClass aClass, final Parameterized[][] values)</strong> </li>

<li><strong>public ArrayValue newArrayWithValue(final ArrayClass aClass, final Parameterized[][][] values)</strong> </li>

<li><strong>public ArrayValue newArrayWithValue(final ArrayClass aClass, final Parameterized[][][][] values)</strong> </li> </ol>

<p>第2,3,4,5方法其實是經過調用第一方法實現的,因此這裏咱們重點討論第一個方法。這些方法都是有兩個參數:</p>

<ol> <li>第一個參數是數組類型和newArray操做是同樣的。 </li>

<li>第二個參數是咱們設置的默認值,雖然咱們定義的是個Object類型的,可是在實際應用的時候必須得是Parameterized的數組類型不然會拋異常。至因而幾維數組,則根據咱們所定義的類型而定。其實asmsupport始終保持着相似於java的編程方式。好比咱們建立一個二維數組那麼咱們能夠說設置這個值爲:new Parameterized[]{new Parameterized[]{p1, p2}}。 </li> </ol>

<p>咱們能夠經過下面的代碼實現:</p>

<div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:4cfdeea5-5b01-4435-ade4-1ea85998cf42" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 902px; height: 93px;" style=" width: 902px; height: 93px;overflow: auto;">av = newArrayWithValue(AClassFactory.getArrayClass(String[].class), new Value[]{Value.value(&quot;array \&quot;s1\&quot; first value&quot;), Value.value(&quot;array \&quot;s1\&quot; second value&quot;)}); LocalVariable s1 = createArrayVariable(&quot;s1&quot;, AClassFactory.getArrayClass(String[].class), false, av);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>

<p><strong>4.建立多維數組的時候同時賦值,建立String[][] s2 = { { &quot;s2[0][0]&quot;, &quot;s2[0][1]&quot; }, { &quot;s2[1][0]&quot;, &quot;s2[1][1]&quot; } }</strong></p>

<p>這裏其實用的也是第三種方式的asmsupport的方法,只不過這個時候咱們須要傳入一個二維數組: </p>

<div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6aa10c73-22e7-4e8b-bcea-9c4c7f6496e9" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 1007px; height: 161px;" style=" width: 1007px; height: 161px;overflow: auto;">Value s200 = Value.value(&quot;s2[0][0]&quot;); Value s201 = Value.value(&quot;s2[0][1]&quot;); Value s210 = Value.value(&quot;s2[1][0]&quot;); Value s211 = Value.value(&quot;s2[1][1]&quot;);

av = newArrayWithValue(AClassFactory.getArrayClass(String[][].class), new Value[][]{new Value[]{s200, s201}, new Value[]{s210, s211}}); LocalVariable s2 = createArrayVariable("s2", AClassFactory.getArrayClass(String[][].class), false, av);</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>

<p>這裏就是建立數組的部分。</p>

<h3><font style="font-weight: bold">獲取數組的長度</font></h3>

<hr />

<p>獲取數組長度採用的方法是<strong>jw.asmsupport.block.ProgramBlock</strong>的:</p>

<p>&#160;<strong><font color="#f79646">public final ArrayLength arrayLength(IVariable arrayReference, Parameterized... dims):</font></strong></p>

<ul> <li><strong><font color="#000000">參數</font></strong> </li> </ul>

<ol> <li>數組對象 </li>

<li>數組的每一個維度的下標,好比咱們要獲取i[0][1].length, 咱們就調用arrayLength(a, Value.value(0), Value.value(1)) </li> </ol>

<ul> <li><strong>返回類型</strong> </li> </ul>

<p>返回類型是<strong>jw.asmsupport.operators.array.ArrayLength</strong>,他是asmsupport對獲取length操做的抽象.</p>

<h3><font style="font-weight: bold">獲取數組每一個元素的內容 </font></h3>

<hr />

<p>獲取每一個元素採用的方法是<strong>jw.asmsupport.block.ProgramBlock</strong>的:</p>

<p><strong><font color="#f79646">public final ArrayLoader arrayLoad(IVariable arrayReference, Parameterized pardim, Parameterized... parDims):</font></strong></p>

<ul> <li><strong><font color="#000000">參數</font></strong> </li> </ul>

<ol> <li>數組對象 </li>

<li>第一維的數組的下標 </li>

<li>第二維開始,每一個維度的下標 </li> </ol>

<ul> <li><strong>返回類型</strong> </li> </ul>

<p>返回類型是<strong>jw.asmsupport.operators.array.ArrayLoader</strong>,他是asmsupport對獲取獲取數組元素操做的抽象.</p>

<h3><font style="font-weight: bold">爲數組元素賦值</font></h3>

<hr />

<p>爲數組元素賦值採用的方法是<strong>jw.asmsupport.block.ProgramBlock</strong>的:</p>

<p><strong><font color="#f79646">public final ArrayStorer arrayStore(IVariable arrayReference, Parameterized value, Parameterized dim, Parameterized... dims):</font></strong></p>

<ul> <li><strong><font color="#000000">參數</font></strong> </li> </ul>

<ol> <li>數組對象 </li>

<li>爲數組元素賦予的值 </li>

<li>第一維的數組的下標 </li>

<li>第二維開始,每一個維度的下標 </li> </ol>

<ul> <li><strong>返回類型</strong> </li> </ul>

<p>返回類型是<strong>jw.asmsupport.operators.array.ArrayStorer</strong>,他是asmsupport對獲取獲取數組元素操做的抽象.</p>

<h3><font style="font-weight: bold">實例</font></h3>

<hr />

<p>咱們須要生成以下代碼:</p>

<div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1675aea4-a49c-4bfb-be4e-a86977fcab5b" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 796px; height: 474px;" style=" width: 796px; height: 474px;overflow: auto;">public static void willGenerate(){ int[][] i1 = new int[2][2]; System.out.println(&quot;i1 = &quot; + ArrayUtils.toString(i1));

int[][] i2 = new int[2][];
System.out.println(&quot;i2 = &quot; + ArrayUtils.toString(i2));

String[] s1 = { &quot;array \&quot;s1\&quot; first value&quot;, &quot;array \&quot;s1\&quot; second value&quot; };
System.out.println(&quot;s1 = &quot; + ArrayUtils.toString(s1));

String[][] s2 = { { &quot;s2[0][0]&quot;, &quot;s2[0][1]&quot; }, { &quot;s2[1][0]&quot;, &quot;s2[1][1]&quot; } };
System.out.println(&quot;s2 = &quot; + ArrayUtils.toString(s2));

//獲取數組長度操做
System.out.println(&quot;length of s2 is &quot; + s2.length);
System.out.println(&quot;length of s2[0] is &quot; + s2[0].length);

//獲取數組內容的操做
System.out.println(&quot;value of s2[0] is &quot; + ArrayUtils.toString(s2[0]));
System.out.println(&quot;value of s2[0][0] is &quot; + ArrayUtils.toString(s2[0][0]));

//爲數組內容賦值的操做
s2[0] = new String[]{ &quot;new s2[0][0]&quot;, &quot;new s2[0][1]&quot; };
s2[1][0] = &quot;new s2[1][0]&quot;;
System.out.println(&quot;new value of s2 is : &quot; + ArrayUtils.toString(s2));

}</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>

<p>對應的asmsupport的代碼以下:</p>

<div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d69c19ba-b885-42ad-9dad-3f98f02f0731" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 796px; height: 2224px;" style=" width: 796px; height: 2224px;overflow: auto;">package example.operators;

import org.apache.commons.lang.ArrayUtils; import org.objectweb.asm.Opcodes;

import jw.asmsupport.Parameterized; import jw.asmsupport.block.method.common.StaticMethodBody; import jw.asmsupport.clazz.AClass; import jw.asmsupport.clazz.AClassFactory; import jw.asmsupport.creator.ClassCreator; import jw.asmsupport.definition.value.Value; import jw.asmsupport.definition.variable.LocalVariable; import jw.asmsupport.operators.array.ArrayValue;

import example.AbstractExample;

/**

  • 在這個例子中咱們將實現數組的相關操做
  • @author 溫斯羣(Joe Wen)

*/ public class ArrayOperatorGenerate extends AbstractExample {

/**
 * @param args
 */
public static void main(String[] args) {
	ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC , &quot;generated.operators.ArrayOperatorGenerateExample&quot;, null, null);
	
	creator.createStaticMethod(&quot;main&quot;, new AClass[]{AClassFactory.getProductClass(String[].class)}, new String[]{&quot;args&quot;}, null, null,
			Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, new StaticMethodBody(){

		@Override
		public void generateBody(LocalVariable... argus) {
			/*
			 * 1.首先咱們須要建立一個數組。咱們有兩隻方式建立數組,第一種是在建立數組的時候
			 *   爲其分配數組空間。第二種是建立數組的時候爲其分配初試值
			 */
			//int[][] i1 = new int[1][2];
			//System.out.println(ArrayUtils.toString(i1));
			
			/*
			 * 
			 * 對應以下代碼:
			 * int[][] i1 = new int[1][2];
			 * System.out.println(&quot;i1 = &quot; + ArrayUtils.toString(i1));
			 */
			ArrayValue av = newArray(AClassFactory.getArrayClass(int[][].class), Value.value(2), Value.value(2));
			LocalVariable i1 = createArrayVariable(&quot;i1&quot;, AClassFactory.getArrayClass(int[][].class), false, av);
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;i1 = &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, i1)));
			
			/*
			 * 下面一段代碼將生成以下代碼:
			 * int[][] i2 = new int[2][];
	         * System.out.println(&quot;i2 = &quot; + ArrayUtils.toString(i2));
			 */
			av = newArray(AClassFactory.getArrayClass(int[][].class), Value.value(2));
			LocalVariable i2 = createArrayVariable(&quot;i2&quot;, AClassFactory.getArrayClass(int[][].class), false, av);
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;i2 = &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, i2)));
			
			/*
			 * 對應以下代碼:
			 * String[] s1 = new String[]{&quot;array \&quot;s1\&quot; first value&quot;, &quot;array \&quot;s1\&quot; second value&quot;};
			 * System.out.println(&quot;s1 = &quot; + ArrayUtils.toString(s1));
			 */
			av = newArrayWithValue(AClassFactory.getArrayClass(String[].class), new Value[]{Value.value(&quot;array \&quot;s1\&quot; first value&quot;), Value.value(&quot;array \&quot;s1\&quot; second value&quot;)});
			LocalVariable s1 = createArrayVariable(&quot;s1&quot;, AClassFactory.getArrayClass(String[].class), false, av);
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;s1 = &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, s1)));

			/*
			 * 對應以下代碼:
			 * String[][] s2 = {{&quot;s2[0][0]&quot;, &quot;s2[0][1]&quot;},{&quot;s2[1][0]&quot;, &quot;s2[1][1]&quot;}};
	         * System.out.println(&quot;s2 = &quot; + ArrayUtils.toString(s2));
			 */
			Value s200 = Value.value(&quot;s2[0][0]&quot;);
			Value s201 = Value.value(&quot;s2[0][1]&quot;);
			Value s210 = Value.value(&quot;s2[1][0]&quot;);
			Value s211 = Value.value(&quot;s2[1][1]&quot;);
			
			av = newArrayWithValue(AClassFactory.getArrayClass(String[][].class), 
					new Value[][]{new Value[]{s200, s201}, new Value[]{s210, s211}});
			LocalVariable s2 = createArrayVariable(&quot;s2&quot;, AClassFactory.getArrayClass(String[][].class), false, av);
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;s2 = &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, s2)));

			/*
			 * 接下來咱們將獲取數組的長度:
			 * 代碼以下:
			 * System.out.println(&quot;length of s2 is &quot; + s2.length);
			 * System.out.println(&quot;length of s2[0] is &quot; + s2[0].length);
			 */
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;length of s2 is &quot;), arrayLength(s2)));
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;length of s2[0] is &quot;), arrayLength(s2, Value.value(0))));

			/*
			 * 接下來咱們將實現如何獲取數組的值
			 * 代碼以下:
			 * System.out.println(&quot;value of s2[0] is &quot; + ArrayUtils.toString(s2[0]));
			 * System.out.println(&quot;value of s2[0][0] is &quot; + s2[0][0]);
			 */
			//s2[0]
			Parameterized arrayLoader = arrayLoad(s2, Value.value(0));
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;value of s2[0] is &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, arrayLoader)));
			
			//s2[0][0]
			arrayLoader = arrayLoad(s2, Value.value(0), Value.value(0));
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;value of s2[0][0] is &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, arrayLoader)));
			
			/*
			 * 接下來是如何實現爲數組單元賦值的操做
			 * 代碼以下
			 * s2[0] = new String[]{&quot;new s2[0][0]&quot;, &quot;new s2[0][1]&quot;};
			 * s2[1][0] = &quot;new s2[1][0]&quot;
			 * System.out.println(&quot;new value of s2 is : &quot; + ArrayUtils.toString(s2));
			 */
			arrayStore(s2, newArrayWithValue(AClassFactory.getArrayClass(String[].class), new Parameterized[]{Value.value(&quot;new s2[0][0]&quot;), Value.value(&quot;new s2[0][1]&quot;)}), Value.value(0));
			arrayStore(s2, Value.value(&quot;new s2[1][0]&quot;), Value.value(1), Value.value(0));
			invoke(systemOut, &quot;println&quot;, append(Value.value(&quot;new value of s2 is : &quot;), invokeStatic(AClassFactory.getProductClass(ArrayUtils.class), &quot;toString&quot;, s2)));
			
			runReturn();
		}
    });
	generate(creator);
}

} </pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div>

相關文章
相關標籤/搜索