![]() |
|||
![]() ![]() |
![]() |
|
![]() |
Creating new objects Now that you know how to work with fields and methods in Java byte code, the only object instruction left is the creation of new objects. There is a single instruction to create new objects, the appropriately named new instruction. Listing 5-8 is a very simple class that does one thing: create a new java.lang.Integer object with the value 7. Listing 5-8 Create a new object class newTest { public void makeInteger() { Integer i = new Integer(7); } } Listing 5-9 shows the byte code for this example. Notice the new instruction at byte 0 of the makeInteger() method. This is followed by the two bytes of a signed short with the value 3. If you guessed that this 3 is an index into the constant pool, you are correct. Entry 3 in the constant pool is a ClassInfo structure that points to the UTF8 structure in entry 19 of the constant pool. That entry is java/lang/Integer, and it tells the new instruction to create a new object of type java.lang.Integer. The new instruction only allocates space for the object in the virtual machine. It does not initialize it. The constructor still needs to be called. Bytes 3 and 4 push the argument for the constructor onto the stack. Bytes 5 through 7 invoke the constructor with the invokespecial instruction. Finally, byte 8 returns void. Listing 5-9 Byte code for the new operator class newTest extends java.lang.Object { public void makeInteger() { 0 new 1 0 2 3 3 bipush 4 7 5 invokespecial 6 0 7 5 8 return } void <init>() { 0 aload_0 1 invokespecial 2 0 3 4 4 return } } /* 1: ClassInfo 20 2: ClassInfo 22 3: ClassInfo 19 4: MethodRef ClassIndex: 1; NameAndTypeIndex: 7 5: MethodRef ClassIndex: 3; NameAndTypeIndex: 6 6: NameAndType NameIndex: 21; DescriptorIndex: 9 7: NameAndType NameIndex: 21; DescriptorIndex: 24 8: UTF8 this 9: UTF8 (I)V 10: UTF8 newTest.java 11: UTF8 ConstantValue 12: UTF8 LocalVariableTable 13: UTF8 Exceptions 14: UTF8 LineNumberTable 15: UTF8 SourceFile 16: UTF8 LocalVariables 17: UTF8 Code 18: UTF8 makeInteger 19: UTF8 java/lang/Integer 20: UTF8 java/lang/Object 21: UTF8 <init> 22: UTF8 newTest 23: UTF8 LnewTest; 24: UTF8 ()V */ ArraysIn Java, arrays are objects and array variables are references. However, there are four byte codes that operate specifically on arrays. The newarray instruction allocates new arrays of primitive types such as int and double. The anewarray instruction allocates new arrays of references. The multianewarray instruction allocates multidimensional arrays of any type. The arraylength instruction returns the length of an array. The iaload, laload, faload, daload, aaload, baload, caload, and saload instructions copy values from an array onto a stack. The iastore, lastore, fastore, dastore, aastore, bastore, castore, and satore instructions pop values from the stack and put them in an array. Creating arrays When you write a statement like int[] e = new int[7]; Java must allocate the right amount of space in the heap for an array of seven ints. To do this, it first pushes the value 7 onto the stack. Then it uses the newarray instruction to actually allocate the space. The number of ints to allocate is popped from the stack. The type of the array to allocate is read from the next byte in the code array. An int array is type 11. A reference to the array is pushed onto the stack. This reference is then popped from the stack and copied into whichever position e occupies in the local variable array. Thus, the byte code would look something like this: bipush 7 newarray 11 astore_1 The newarray instruction knows the sizes of the different types it can hold and allocates the appropriate amount of space.
Arrays are one of the few areas in Java in which all primitive data types are supported equally. Short arrays really are arrays of shorts and not just a subset of ints. Although the difference in storage requirements between a single short variable and a single int variable is trivial on modern computers, the difference between a large array of shorts and a large array of ints can still be significant. anewarray Arrays of objects are really arrays of references. The type of such an array is given as a 2-byte index into the constant pool that follows the anewarray instruction. Like the newarray instruction, the length of the array is popped from the stack, and a reference to the new array is pushed onto the stack. Thus, Integer[] e = new Integer[7]; might compile to something like this: 0 bipush 1 7 2 anewarray 3 0 4 3 5 astore_1 ... /* Constant Pool 1: ClassInfo 21 2: ClassInfo 23 3: ClassInfo 20 ... 20: UTF8 java/lang/Integer ... The difference between newarray and anewarray is that newarray encodes the type of the data directly into the code array, whereas anewarray needs to refer to the constant pool.
|
![]() |
|