Array initialization | CodeGuru

Array initialization

Bruce Eckel’s Thinking in Java Contents | Prev | Next Initializing arrays in C is error-prone and tedious. C++ uses aggregate initialization to make it much safer. [22] Java has no “aggregates” like C++, since everything is an object in Java. It does have arrays, and these are supported with array initialization. An array is […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 1, 2001
6 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Initializing


arrays in C is error-prone and tedious. C++ uses


aggregate
initialization

to make it much safer.


[22]

Java has no “aggregates” like C++, since everything is an object in


Java. It does have arrays, and these are supported with

array
initialization.

An


array is simply a sequence of either objects or primitives, all the same type


and packaged together under one identifier name. Arrays are defined and used


with the square-brackets

indexing
operator

[ ].
To define an array you simply follow your type name with empty square brackets:
int[]
a1;

You


can also put the square brackets after the identifier to produce exactly the


same meaning:

int
a1[];

This


conforms to expectations from C and C++ programmers. The former style, however,


is probably a more sensible syntax, since it says that the type is “an


int

array.” That style will be used in this book.

The


compiler doesn’t allow you to tell it how big the array is. This brings


us back to that issue of “handles.” All that you have at this point


is a handle to an array, and there’s been no space allocated for the


array. To create storage for the array you must write an initialization


expression. For arrays, initialization can appear anywhere in your code, but


you can also use a special kind of initialization expression that must occur at


the point where the array is created. This special initialization is a set of


values surrounded by curly braces. The storage allocation (the equivalent of


using


new

)


is taken care of by the compiler in this case. For example:

int[]
a1 = { 1, 2, 3, 4, 5 };

So


why would you ever define an array handle without an array?

int[]
a2;

Well,


it’s possible to assign one array to another in Java, so you can say:

a2
= a1;

What


you’re really doing is copying a handle, as demonstrated here:

//: Arrays.java
// Arrays of primitives.
 
public class Arrays {
  public static void main(String[] args) {
    int[] a1 = { 1, 2, 3, 4, 5 };
    int[] a2;
    a2 = a1;
    for(int i = 0; i < a2.length; i++)
      a2[i]++;
    for(int i = 0; i < a1.length; i++)
      prt("a1[" + i + "] = " + a1[i]);
  }
  static void prt(String s) {
    System.out.println(s);
  }
} ///:~ 

You


can see that


a1

is given an initialization value while


a2

is not;


a2

is assigned later – in this case, to another array.

There’s


something new here: all arrays have an intrinsic member (whether they’re


arrays of objects or arrays of primitives) that you can query – but not


change – to tell you how many elements there are in the array. This


member is


length

.


Since arrays in Java, like C and C++, start counting from element zero, the


largest element you can index is


length
– 1

.


If you go out of

bounds,
C and C++ quietly accept this and allow you to stomp all over your memory,
which is the source of many infamous bugs. However, Java protects you against
such problems by causing a run-time error (an
exception,
the subject of Chapter 9) if you step out of bounds. Of course, checking every
array access costs time and code and there’s no way to turn it off, which
means that array accesses might be a source of inefficiency in your program if
they occur at a critical juncture. For Internet security and programmer
productivity, the Java designers thought that this was a worthwhile tradeoff.

What


if you don’t know how many elements you’re going to need in your


array while you’re writing the program? You simply use


new

to create the elements in the array. Here,

new
works even though it’s creating an array of primitives (
new
won’t create a non-array primitive):
//: ArrayNew.java
// Creating arrays with new.
import java.util.*;
 
public class ArrayNew {
  static Random rand = new Random();
  static int pRand(int mod) {
    return Math.abs(rand.nextInt()) % mod;
  }
  public static void main(String[] args) {
    int[] a;
    a = new int[pRand(20)];
    prt("length of a = " + a.length);
    for(int i = 0; i < a.length; i++)
      prt("a[" + i + "] = " + a[i]);
  }
  static void prt(String s) {
    System.out.println(s);
  }
} ///:~ 

Since


the size of the array is chosen at random (using the


pRand( )

method defined earlier), it’s clear that array creation is actually


happening at run-time. In addition, you’ll see from the output of this


program that array elements of primitive types are automatically initialized to


”empty” values. (For numerics, this is zero, for


char

,


it’s


null

,


and for


boolean

,


it

s


false

.)

Of


course, the array could also have been defined and initialized in the same


statement:

int[]
a = new int[pRand(20)];

If


you’re dealing with an array of non-primitive objects, you must always use


new

.


Here, the handle issue comes up again because what you create is an array of


handles. Consider the wrapper type


Integer,

which is a class and not a primitive:

//: ArrayClassObj.java
// Creating an array of non-primitive objects.
import java.util.*;
 
public class ArrayClassObj {
  static Random rand = new Random();
  static int pRand(int mod) {
    return Math.abs(rand.nextInt()) % mod;
  }
  public static void main(String[] args) {
    Integer[] a = new Integer[pRand(20)];
    prt("length of a = " + a.length);
    for(int i = 0; i < a.length; i++) {
      a[i] = new Integer(pRand(500));
      prt("a[" + i + "] = " + a[i]);
    }
  }
  static void prt(String s) {
    System.out.println(s);
  }
} ///:~ 

Here,


even after


new

is called to create the array:

Integer[]
a = new Integer[pRand(20)];

it’s


only an array of handles, and not until the handle itself is initialized by


creating a new


Integer

object is the initialization complete:

a[i]
= new Integer(pRand(500));

If


you forget to create the object, however, you’ll get an exception at


run-time when you try to read the empty array location.

Take


a look at the formation of the


String

object


inside the print statements. You can see that the handle to the


Integer

object is automatically converted to produce a


String

representing


the value inside the object.

It’s


also possible to initialize arrays of objects using the curly-brace-enclosed


list. There are two forms, the first of which is the only one allowed in Java 1.0

.
The second (equivalent) form is allowed starting with Java 1.1
:
//: ArrayInit.java
// Array initialization
 
public class ArrayInit {
  public static void main(String[] args) {
    Integer[] a = {
      new Integer(1),
      new Integer(2),
      new Integer(3),
    };
 
    // Java 1.1 only:
    Integer[] b = new Integer[] {
      new Integer(1),
      new Integer(2),
      new Integer(3),
    };
  }
} ///:~ 

This


is useful at times, but it’s more limited since the size of the array is


determined at compile time. The final comma in the list of initializers is


optional. (This feature makes for easier maintenance of long lists.)

The


second form of array initialization, added in Java 1.1

,
provides a convenient syntax to create and call methods that can produce the
same effect as C’s
variable
argument lists

(known as “varargs” in C). These included, if you choose, unknown
quantity of arguments as well as unknown type. Since all classes are ultimately
inherited from the common root class
Object,
you can create a method that takes an array of
Object
and call it like this:
//: VarArgs.java
// Using the Java 1.1 array syntax to create
// variable argument lists
 
class A { int i; }
 
public class VarArgs {
  static void f(Object[] x) {
    for(int i = 0; i < x.length; i++)
      System.out.println(x[i]);
  }
  public static void main(String[] args) {
    f(new Object[] {
        new Integer(47), new VarArgs(),
        new Float(3.14), new Double(11.11) });
    f(new Object[] {"one", "two", "three" });
    f(new Object[] {new A(), new A(), new A()});
  }
} ///:~ 

At


this point, there’s not much you can do with these unknown objects, and


this program uses the automatic


String

conversion to do something useful with each


Object

.


In Chapter 11 (run-time type identification or RTTI) you’ll learn how to


discover the exact type of such objects so that you can do something more


interesting with them.


Multidimensional
arrays

Java


allows you to easily create

multidimensional
arrays:
//: MultiDimArray.java
// Creating multidimensional arrays.
import java.util.*;
 
public class MultiDimArray {
  static Random rand = new Random();
  static int pRand(int mod) {
    return Math.abs(rand.nextInt()) % mod;
  }
  public static void main(String[] args) {
    int[][] a1 = {
      { 1, 2, 3, },
      { 4, 5, 6, },
    };
    for(int i = 0; i < a1.length; i++)
      for(int j = 0; j < a1[i].length; j++)
        prt("a1[" + i + "][" + j +
            "] = " + a1[i][j]);
    // 3-D array with fixed length:
    int[][][] a2 = new int[2][2][4];
    for(int i = 0; i < a2.length; i++)
      for(int j = 0; j < a2[i].length; j++)
        for(int k = 0; k < a2[i][j].length;
            k++)
          prt("a2[" + i + "][" +
              j + "][" + k +
              "] = " + a2[i][j][k]);
    // 3-D array with varied-length vectors:
    int[][][] a3 = new int[pRand(7)][][];
    for(int i = 0; i < a3.length; i++) {
      a3[i] = new int[pRand(5)][];
      for(int j = 0; j < a3[i].length; j++)
        a3[i][j] = new int[pRand(5)];
    }
    for(int i = 0; i < a3.length; i++)
      for(int j = 0; j < a3[i].length; j++)
        for(int k = 0; k < a3[i][j].length;
            k++)
          prt("a3[" + i + "][" +
              j + "][" + k +
              "] = " + a3[i][j][k]);
    // Array of non-primitive objects:
    Integer[][] a4 = {
      { new Integer(1), new Integer(2)},
      { new Integer(3), new Integer(4)},
      { new Integer(5), new Integer(6)},
    };
    for(int i = 0; i < a4.length; i++)
      for(int j = 0; j < a4[i].length; j++)
        prt("a4[" + i + "][" + j +
            "] = " + a4[i][j]);
    Integer[][] a5;
    a5 = new Integer[3][];
    for(int i = 0; i < a5.length; i++) {
      a5[i] = new Integer[3];
      for(int j = 0; j < a5[i].length; j++)
        a5[i][j] = new Integer(i*j);
    }
    for(int i = 0; i < a5.length; i++)
      for(int j = 0; j < a5[i].length; j++)
        prt("a5[" + i + "][" + j +
            "] = " + a5[i][j]);
  }
  static void prt(String s) {
    System.out.println(s);
  }
} ///:~ 

The


code used for printing uses


length

so that it doesn’t depend on fixed array sizes.

The


first example shows a multidimensional array of primitives. You delimit each


vector in the array with curly braces:

    int[][] a1 = {
      { 1, 2, 3, },
      { 4, 5, 6, },
    };

Each


set of square brackets moves you into the next level of the array.

The


second example shows a three-dimensional array allocated with


new

.


Here, the whole array is allocated at once:

int[][][]
a2 = new int[2][2][4];

But


the third example shows that each vector in the arrays that make up the matrix


can be of any length:

    int[][][] a3 = new int[pRand(7)][][];
    for(int i = 0; i < a3.length; i++) {
      a3[i] = new int[pRand(5)][];
      for(int j = 0; j < a3[i].length; j++)
        a3[i][j] = new int[pRand(5)];
    }

The


first


new

creates an array with a random-length first element and the rest undetermined.


The second


new

inside the for loop fills out the elements but leaves the third index


undetermined until you hit the third


new

.

You


will see from the output that array values are automatically initialized to


zero if you don’t give them an explicit initialization value.

You


can deal with arrays of non-primitive objects in a similar fashion, which is


shown in the fourth example, demonstrating the ability to collect many


new

expressions with curly braces:

    Integer[][] a4 = {
      { new Integer(1), new Integer(2)},
      { new Integer(3), new Integer(4)},
      { new Integer(5), new Integer(6)},
    };

The


fifth example shows how an array of non-primitive objects can be built up piece


by piece:

    Integer[][] a5;
    a5 = new Integer[3][];
    for(int i = 0; i < a5.length; i++) {
      a5[i] = new Integer[3];
      for(int j = 0; j < a5[i].length; j++)
        a5[i][j] = new Integer(i*j);
    }

The


i*j

is just to put an interesting value into the


Integer

.


[22]

See


Thinking
in C++

for a complete description of aggregate initialization.

Contents

|

Prev

|

Next
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.