Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


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

  */

Arrays

In 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.

Table 5-3 Type codes for arrays

Code Type

4 boolean
5 char
6 float
7 double
8 byte
9 short
10 int
11 long

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.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.