30

Is there any difference between the following two declarations?

int arr[] = new int [5];

and

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

Is arr1 declared on stack or on the heap?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Muhammad Ali Qadri
  • 606
  • 2
  • 8
  • 21

5 Answers5

36

There is the obvious difference that one has all zeros, and the other contains [1..5].

But that's the only difference. Both are 5-element int arrays, both are allocated in the same way. It is mere syntactic convenience to declare with the braces and no new.

Note that this form can only be used when the array is declared:

int[] blah = {}

But not

int[] blah;
blah = {};

or

return {};

Objects (arrays are objects) are allocated on the heap.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • The second way will work only in the case of array declaration. It cannot be returned from the method, for example. – Andrew Tobilko Aug 19 '16 at 06:44
  • As for your answer in arrays if we dont mention new also it will be taken as the new object and it will allocate the memory in stack..write – Prasanna Kumar H A Aug 19 '16 at 06:47
  • @andytumer Great answer. I was hoping to know if i declare **int i = 10;** then this would also be on heap? Or using the wrapper class **Integer i = 10;** "i" would be declared on heap? – Muhammad Ali Qadri Aug 19 '16 at 06:50
  • 1
    @Andrew updated. I suspect that it works slightly more broadly than you hint (E.g. assignment to an array variable in an expression); but let's not complicate things :) – Andy Turner Aug 19 '16 at 06:53
  • 2
    @Muhammad it depends. If `int i = 10;` is a local variable declaration, 10 is on the stack; if it's a member variable declaration, it's on the heap. `Integer i = 10;` is the same as `Integer.valueOf(10)`, so `i` refers to a value of the heap. – Andy Turner Aug 19 '16 at 06:57
  • @Andrew I'm not actually convinced that I'm right on my last comment: "An array initializer may be specified in a field declaration (§8.3, §9.3) or local variable declaration (§14.4), or as part of an array creation expression (§15.10.1), to create an array and provide some initial values." This implies that my example of assignment in an expression is not a valid context. I'll try this when I get to work... Good thing I was conservative in my assertion! – Andy Turner Aug 19 '16 at 07:04
  • 1
    There seems to be some confusion about what's on the stack and what's on the heap. One thing to remember is that, without exception, local variables are always allocated on the stack. Always. And objects are always allocated on the heap. Now, if you declare a reference to an object such as `Integer i = 10` or `int[] arr = {}` then the _references_ are allocated on the stack but the _objects_ they refer to are allocated on the heap. The references are just pointers that can be assign to point to another object. – Klitos Kyriacou Aug 19 '16 at 07:25
  • @KlitosKyriacou indeed. This is why I carefully worded my comment to say that "10" is on the stack or on the heap; I say nothing about the reference to the value on the heap. But more precisely: "if you declare a *local* reference to an object": if the reference is a class member, it's on the heap too. – Andy Turner Aug 19 '16 at 07:27
  • @AndyTurner your answer is great, I wasn't aiming my comment at your answer but at some of the other commenters such as Muhammad Ali Qadri who asked, "in `Integer i = 10;` would i be declared on the heap?" This sort of question can cause confusion, because when talking about i are we talking about the reference itself or the thing it refers to? I tried to clarify that by my earlier comment. – Klitos Kyriacou Aug 19 '16 at 07:32
  • @KlitosKyriacou fair enough. I was actually thinking of adding this distinction into the answer. – Andy Turner Aug 19 '16 at 07:33
  • "Objects (arrays are objects) are never allocated on the stack." That's not entirely true; look for escape analysis optimizations. – Random42 Aug 19 '16 at 07:45
  • 2
    Bringing Escape Analysis into it doesn’t necessarily improve the answer. EA may even cause an object to never be allocated. Actually, the terms “stack” and “heap” (the way programming languages like C use it) do not match what JVMs do. It’s best to say, objects including arrays are stored in *managed memory*, and forget about the words “stack” and “heap”. – Holger Aug 19 '16 at 08:18
  • 1
    @Holger the JVM spec doesn't mention "managed memory"; but does mention the word ["heap"](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.3): "The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.". – Andy Turner Aug 19 '16 at 08:22
  • 1
    @Andy Turner: that’s why I said, it’s not a heap *the way programming languages like C use it*. If a heap is “*the run-time data area from which memory for all class instances and arrays is allocated*”, then stack-allocated Java objects are still on the heap, per definition. That’s the whole point of my comment, the way “heap” is defined in the JVM is different to how programming languages like C use it. That’s why I suggest not to use the word “heap” for it, but the term *managed memory*, which is the correct term for the colloquial “garbage collected memory”. – Holger Aug 19 '16 at 08:34
  • @Holger you appear to be arguing two things: 1) that EA means the object won't necessarily be allocated at all. I agree with this: from reading more, I've found that its *scalar fields* may be allocated on the stack, but the object itself isn't allocated on the stack; 2) that I shouldn't use the term "heap". I disagree with this: this is the JVM spec's nomenclature. If a reader interprets the term incorrectly, that's on the reader, as it is explained in the spec; they may just as easily interpret the term "managed memory" incorrectly, especially as that is not defined in the spec. – Andy Turner Aug 19 '16 at 09:30
  • @Andy Turner: “*shouldn’t*” is too harsh. I recommend avoiding it where it could confuse the reader, which is almost everytime, a user ask a question like “*Is this object allocated on stack or on the heap?*” (like here). If the asker understood what “heap” means according to the JVM specification, (s)he did not ask such a question as *all* objects are allocated on that heap, as that’s how “*heap*” is defined in the JVM specification, as all other properties of a Java heap are intentionally unspecified. – Holger Aug 19 '16 at 09:47
  • Regarding “not defined in the spec”, you will find the term “*storage management*” four times in the section you have linked yourself. And the thing, an automatic storage management system will manage, is a managed storage. Since “storage” and “memory” are synonyms, you may use either, “*managed storage*” or “*managed memory*”, but I think you will find “*managed memory*” more often in literature (beyond the JVM specification). – Holger Aug 19 '16 at 09:49
  • You'll also find the term "heap" in that same section 13 times. Let's just leave this: I don't think we're going to get anywhere by arguing any further :) – Andy Turner Aug 19 '16 at 09:51
  • Sure, you’ll find the term “heap” there, but in the context of the JVM specification, every reader understand that this term refers to the heap, as the specification itself defines it. This context is important. I only suggest avoiding the term when talking to users not familiar with the specification. A Java heap can be confused with a C heap, a “managed memory” can not. However, you are right, we should end here. – Holger Aug 19 '16 at 10:01
  • RE: "you can generally assume that an object will be allocated on the heap" does an array (of primitives) count as an object? – Celeritas Aug 19 '16 at 12:37
  • 1
    @Celeritas "arrays are objects" Yes. See also [JLS Sec 4.10.3](https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.10.3). – Andy Turner Aug 19 '16 at 12:37
  • AndyTurner, I agree with @Holger. Java concepts don't match with C concepts **at all** (and the OP seems to be falling for that). For instance the JVM actually has **two** stacks, the stack of frames and the operand stack. None of them holds the local variables which have their own storage. Plus JVM frames can be implemented on the *process heap* as linked list, thereby making everything always "on the heap". JVM terms are entirely logical and that justify Holger side in my opinion. – Margaret Bloom Aug 19 '16 at 12:47
8

The first line puts one new object on the heap -an array object holding four elements- with each element containing an int with default value of 0.

The second does the same, but initializing with non default values. Going deeper, this single line does four things:

  • Declares an int array reference variable named arr1
  • Creates an int array with a length of five (five elements).
  • Populates the array's elements with the values 1,2,3,4,5
  • Assigns the new array object to the reference variable arr1

If you use an array of objects instead of primitives:

MyObject[] myArray = new MyObject[3];

then you have one array object on the heap, with three null references of type MyObject, but you don't have any MyObject objects. The next step is to create some MyObject objects and assign them to index positions in the array referenced by myArray.

myArray[0]=new MyObject();
myArray[1]=new MyObject();
myArray[2]=new MyObject();

In conclusion: arrays must always be given a size at the time they are constructed. The JVM needs the size to allocate the appropriate space on the heap for the new array object.

debus
  • 630
  • 4
  • 9
4

I agree with the other answers, by far the most often you array will be allocated on the heap (no matter which of the two declarations you use). However, according to the top answer in Can Java allocate a list on stack?, “in special cases, the java virtual machine may perform escape analysis and decide to allocate objects … on a stack”. I believe that this is true. So the answer to your question is: It depends. Usually on the heap.

Community
  • 1
  • 1
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Interesting. If you don't mind, I will include this fact in my answer - citing this answer, of course. – Andy Turner Aug 19 '16 at 07:47
  • Feel free, by all means. I wish I had found a better source for it, maybe I should just have looked longer. – Ole V.V. Aug 19 '16 at 08:11
  • 2
    There are also JVMs which perform *Escape Detection* at runtime instead of *Escape Analysis* at compile-time. On such a JVM, objects will *always* be allocated on the stack, tagged with a marker, and when the JVM detects that the marker tag escapes the local scope, it will copy the object to the heap and patch up all references to it. Escape Analysis works the other way around: allocate objects on the heap, unless EA can prove the reference does *not* escape. Unfortunately, EA is equivalent to solving the Halting Problem, so there will be allocations that *could* be on the stack but cannot … – Jörg W Mittag Aug 19 '16 at 09:21
  • 1
    … be proven safe by the compiler, so the only sane thing the compiler can do is allocate on the heap. Escape Detection happens at runtime, and so isn't restricted by the Halting Problem. – Jörg W Mittag Aug 19 '16 at 09:21
4
  • new int [5] can be used for both assignment and initialization, but {1, 2} only can be used as declaration with initialization. (Note that new int[] {1, 2} also can be used as both assignment and initialization)

  • new int [5] sets all entries to zero, but {1, 2} and new int[] {1, 2} sets 1 and 2 in respective entries.

  • Both are on heap, you can save their object reference.

    int arr[] = new int [5];
    // arr: object reference to the array
    

    or

    int arr[] = {1, 2, 3, 4, 5};
    // arr: object reference to the array
    

Helpful materials:

Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
3

Objects reside in heap. Arrays are object type in java programming language. Official documentation here

Pravat Panda
  • 1,060
  • 2
  • 13
  • 27