The most efficient way to innitialize an array with an innitialization list

R

Razvan

Hi!





int [] arr = {21, 22, 23};

int [] arr = new int [] {21, 22, 23};

The second form will create an array with 3 elements then it will
copy the values of the innitialization list (21, 22, 23). The first
form just declares a reference to the array {21, 22, 23} - no
suplimentary memory is allocated and no copy operation takes place, so
the first form should be preffered. Is this true ? ... or the compiler
makes some optimizations, practically rendering the 2 forms equivalent
? I doubt that it will, since the new operator guarantees that new
memory will be allocated.



Regards,
Razvan
 
B

Boudewijn Dijkstra

Razvan said:
Hi!





int [] arr = {21, 22, 23};

int [] arr = new int [] {21, 22, 23};

The second form will create an array with 3 elements then it will
copy the values of the innitialization list (21, 22, 23). The first
form just declares a reference to the array {21, 22, 23} - no
suplimentary memory is allocated and no copy operation takes place, so
the first form should be preffered. Is this true ? ... or the compiler
makes some optimizations, practically rendering the 2 forms equivalent
? I doubt that it will, since the new operator guarantees that new
memory will be allocated.

Wrong, wrong, wrong. The second form declares a new reference and when the
line is executed, the VM creates a new array with values copied from the class
file. Both forms produce exactly the same code (CMIIW). The simple fact that
it is an "initialization list" implies that a new object is created no matter
what.
 
T

Tor Iver Wilhelmsen

Boudewijn Dijkstra said:
Wrong, wrong, wrong. The second form declares a new reference and
when the line is executed, the VM creates a new array with values
copied from the class file.

No, it initializes it element by element with constants in the
bytecode. Class files do not have any "data segment" for
initialization code - except for the string literals.

The only difference between them is that the version without "new
type[]" in front of the init data is not allowed inside a method, but
can only be used for declaring member references.
 
B

Boudewijn Dijkstra

Tor Iver Wilhelmsen said:
No, it initializes it element by element with constants in the
bytecode. Class files do not have any "data segment" for
initialization code - except for the string literals.

The constant pool of a class file may contain literal Strings, ints, floats,
longs and doubles. If the elements cannot be represented by short or byte
values, the constants cannot be put in the bytecode (without adding shifting
instructions).
 
R

Razvan

No, it initializes it element by element with constants in the
bytecode. Class files do not have any "data segment" for
initialization code - except for the string literals.

I see. If there is no data segment that means that both forms are
equivalent. I mean the array is allocated each time and
the list of constants is copied from the class file.
The only difference between them is that the version without "new
type[]" in front of the init data is not allowed inside a method, but
can only be used for declaring member references.

You are wrong. Check this:


class SimpleJava
{
static int br1 [] = {3, 4, 5}; // 1st form - class variable
static int br2 [] = new int [] {13, 14, 15}; // 2nd form - class
variable


int br3 [] = {6, 7, 8}; // 1st form - instance variable
int br4 [] = new int [] {16, 17, 18}; // 2nd form - instance
variable


public static void main(String args[])
{
System.out.println("SimpleJava ....");


int arr1 [] = {11, 15, 19}; // 1st form - inside a method
int arr2 [] = new int [] {111, 115, 119}; // 2nd form - inside a
method

System.out.println("arr1[1] = " + arr1[1]);
System.out.println("arr2[1] = " + arr2[1]);

System.out.println("br1[1] = " + br1[1]);
System.out.println("br2[1] = " + br2[1]);


SimpleJava sj = new SimpleJava();

System.out.println("br3[1] = " + sj.br3[1]);
System.out.println("br4[1] = " + sj.br4[1]);
}
}


Both forms can be used without any problems in a method ("main()" in
this case). More: both forms can be used to declare class & instance
attributes (br1, br2 & br3, br4).


If you were reffering to something else please post a piece of code
to proove your theory.



Regards,
Razvan
 
R

Razvan

Wrong, wrong, wrong. The second form declares a new reference and
when the
line is executed, the VM creates a new array with values copied from
the class
file. Both forms produce exactly the same code (CMIIW).

I have to trust you here. My assembler skills have not been used in
years.

Observation:
The first form also declares a new reference.


The simple fact that it is an "initialization list" implies that a new
object is created no matter what.

No matter what ?! What is this suppose to mean ? Even if there is no
memory to allocate the array ?

When the new object is not "created no matter what" ?



Regards,
Razvan
 
B

Boudewijn Dijkstra

Razvan said:
I have to trust you here. My assembler skills have not been used in
years.

Observation:
The first form also declares a new reference.
Correct.


No matter what ?! What is this suppose to mean ? Even if there is no
memory to allocate the array ?

When the new object is not "created no matter what" ?

I was a bit confused by your original post. You said:

You seem to imply here that the array {21, 22, 23} already existed before the
variable was declared. That the second form just defines a reference to it.
Class files cannot store entire array objects. Maybe you were thinking that
there can be array literals just like String literals, where the same literal
refers to the same object.

Well, the VM specification says this:
<quote>
A literal is the source code representation of a value of a primitive type,
the String type, or the null type. String literals and, more generally,
strings that are the values of constant expressions are "interned" so as to
share unique instances, using the method String.intern.

The null type has one value, the null reference, denoted by the literal null.
The boolean type has two values, denoted by the literals true and false.
</quote>
 
J

John K

int [] arr = {21, 22, 23};
int [] arr = new int [] {21, 22, 23};

Both of these produce the exact same bytecode:

public class Arrays {
static int a [] = {3, 4, 5};
static int b [] = new int [] {3, 4, 5};
}

Run "javap -classpath . -c Arrays"

Relevant output:

static {};
Code:
0: iconst_3
1: newarray int
3: dup
4: iconst_0
5: iconst_3
6: iastore
7: dup
8: iconst_1
9: iconst_4
10: iastore
11: dup
12: iconst_2
13: iconst_5
14: iastore
15: putstatic #12; //Field a:[I
18: iconst_3
19: newarray int
21: dup
22: iconst_0
23: iconst_3
24: iastore
25: dup
26: iconst_1
27: iconst_4
28: iastore
29: dup
30: iconst_2
31: iconst_5
32: iastore
33: putstatic #14; //Field b:[I
36: return

As you can see they are identical.

-John K
 
M

Mike Schilling

Razvan said:
Hi!





int [] arr = {21, 22, 23};

int [] arr = new int [] {21, 22, 23};

The second form will create an array with 3 elements then it will
copy the values of the innitialization list (21, 22, 23). The first
form just declares a reference to the array {21, 22, 23} - no
suplimentary memory is allocated and no copy operation takes place, so
the first form should be preffered. Is this true ? ... or the compiler
makes some optimizations, practically rendering the 2 forms equivalent
? I doubt that it will, since the new operator guarantees that new
memory will be allocated.

They're identical in meaning and in result. IIRC, the former is the
original Java syntax for array initialization and the latter was introduced
as a way of constructing unnamed arrays in 1.1 or so.
 
M

Mike Schilling

Razvan said:
No, it initializes it element by element with constants in the
bytecode. Class files do not have any "data segment" for
initialization code - except for the string literals.

I see. If there is no data segment that means that both forms are
equivalent. I mean the array is allocated each time and
the list of constants is copied from the class file.
The only difference between them is that the version without "new
type[]" in front of the init data is not allowed inside a method, but
can only be used for declaring member references.

You are wrong. Check this:


class SimpleJava
{
static int br1 [] = {3, 4, 5}; // 1st form - class variable
static int br2 [] = new int [] {13, 14, 15}; // 2nd form - class
variable


int br3 [] = {6, 7, 8}; // 1st form - instance variable
int br4 [] = new int [] {16, 17, 18}; // 2nd form - instance
variable


public static void main(String args[])
{
System.out.println("SimpleJava ....");


int arr1 [] = {11, 15, 19}; // 1st form - inside a method
int arr2 [] = new int [] {111, 115, 119}; // 2nd form - inside a
method

System.out.println("arr1[1] = " + arr1[1]);
System.out.println("arr2[1] = " + arr2[1]);

System.out.println("br1[1] = " + br1[1]);
System.out.println("br2[1] = " + br2[1]);


SimpleJava sj = new SimpleJava();

System.out.println("br3[1] = " + sj.br3[1]);
System.out.println("br4[1] = " + sj.br4[1]);
}
}


Both forms can be used without any problems in a method ("main()" in
this case). More: both forms can be used to declare class & instance
attributes (br1, br2 & br3, br4).


If you were reffering to something else please post a piece of code
to prove your theory.

What Tor meant to say, I think, is that the version with no "new Type[]" can
only be used to initialize an array-typed referemce, while the other can be
used within any expression. That is:

int arr1 [] = {11, 15, 19}; // good
int arr2 [] = new int [] {111, 115, 119}; //good

method(new int [] {111, 115, 119}) // good
method({11, 15, 19}) // *bad*

The reason being that in the bad case there's nothing to indicate the type
of the array (byte[]? short[]? long[]?)
 
D

Dale King

Mike Schilling said:
What Tor meant to say, I think, is that the version with no "new Type[]" can
only be used to initialize an array-typed referemce, while the other can be
used within any expression. That is:

int arr1 [] = {11, 15, 19}; // good
int arr2 [] = new int [] {111, 115, 119}; //good

method(new int [] {111, 115, 119}) // good
method({11, 15, 19}) // *bad*

The reason being that in the bad case there's nothing to indicate the type
of the array (byte[]? short[]? long[]?)

At one point there was a proposal to allow something along these lines. It
was JSR-65 for concise array literals. It was basically replaced with the
new varargs feature in 1.5 which allows you to do the same without the
braces but only for the last argument.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top