145

I can write:

AClass[] array = {object1, object2}

I can also write:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

but I can't write:

AClass[] array;
...
array = {object1, object2};

Why is this blocked by Java?

I know how to work around it, but from time to time it would be simpler.

For example:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

This simple question that has been bugging me since I learned how to play with arrays in Java.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Jason Rogers
  • 18,658
  • 25
  • 74
  • 110

4 Answers4

141

Why is this blocked by Java?

You'd have to ask the Java designers. There might be some subtle grammatical reason for the restriction. Note that some of the array creation / initialization constructs were not in Java 1.0, and (IIRC) were added in Java 1.1.

But "why" is immaterial ... the restriction is there, and you have to live with it.

I know how to work around it, but from time to time it would be simpler.

You can write this:

AClass[] array;
...
array = new AClass[]{object1, object2};
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Stephen C
  • 632,615
  • 86
  • 730
  • 1,096
  • 9
    w/o the new declaration there would be no difference between a statement block and array initializer (like in javascript, which can be misleading} – bestsss Mar 22 '11 at 07:39
  • 10
    It *would* be confusing ... and hard to parse. Consider if `{o1()}` was a valid expression and `{o1();}` was a valid statement block. The parser has to get to the '}' or ';' before it can distinguish the two cases. The grammatical issue is not subtle at all!! – Stephen C Mar 22 '11 at 11:12
19

I'll try to answer the why question: The Java array is very simple and rudimentary compared to classes like ArrayList, that are more dynamic. Java wants to know at declaration time how much memory should be allocated for the array. An ArrayList is much more dynamic and the size of it can vary over time.

If you initialize your array with the length of two, and later on it turns out you need a length of three, you have to throw away what you've got, and create a whole new array. Therefore the 'new' keyword.

In your first two examples, you tell at declaration time how much memory to allocate. In your third example, the array name becomes a pointer to nothing at all, and therefore, when it's initialized, you have to explicitly create a new array to allocate the right amount of memory.

I would say that (and if someone knows better, please correct me) the first example

AClass[] array = {object1, object2}

actually means

AClass[] array = new AClass[]{object1, object2};

but what the Java designers did, was to make quicker way to write it if you create the array at declaration time.

The suggested workarounds are good. If the time or memory usage is critical at runtime, use arrays. If it's not critical, and you want code that is easier to understand and to work with, use ArrayList.

prograde
  • 2,092
  • 2
  • 20
  • 30
  • 3
    This is a shortcut as you have stated, Quoting Oracle: ["Alternatively, you can use the shortcut syntax to create and initialize an array"](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html). The reason maybe that *an array must be given some space in memory* using new at some point. New is implicit in the shortcut, but the shortcut is valid only in the declaration. Elsewhere, there is no shortcut allowed, and new is mandatory. – mins Aug 02 '14 at 13:17
  • 4
    I'm sorry, but your attempt at answering the "why" question does not hold water. The compiler would be able to work out how big the array needed to be by counting the expressions between the `{` and the `}` ... just like it does for the initializer forms that are allowed. – Stephen C Feb 06 '16 at 04:03
8

I can't answer the why part.

But if you want something dynamic then why don't you consider Collection ArrayList.

ArrrayList can be of any Object type.

And if as an compulsion you want it as an array you can use the toArray() method on it.

For example:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

I hope this might help you.

lesmana
  • 22,750
  • 8
  • 73
  • 83
Amanpreet
  • 520
  • 3
  • 12
  • 2
    There is no need to cast the return type of the Array to String[]. By contract the returned Array is of the same type as the specified array. http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#toArray(T[]) – Ankur Agarwal Dec 07 '13 at 05:29
4

For those of you, who doesn't like this monstrous new AClass[] { ... } syntax, here's some sugar:

public AClass[] c(AClass... arr) { return arr; }

Use this little function as you like:

AClass[] array;
...
array = c(object1, object2);
user123
  • 103
  • 5