Question Details

No question body available.

Tags

java arrays reference initialization

Answers (3)

March 31, 2026 Score: 6 Rep: 108,093 Quality: High Completeness: 80%

Are arrays reference types

Yes, they are.

I am confused, because when I reference this site: https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.5, it states that reference types get initialized to null.

That is not what that says.

What it says is:

Each class variable, instance variable, or array component is initialized with a default value when it is created.

You've skipped that part and just zoomed in on the list below that paragraph which indicates which value such elements are initialized to.

The int[] c; in your example code is none of the things listed in this paragraph. It is not a class variable or instance variable (it is a local variable; class variables are written at the X position in class SomeType { static int X; int Y; } and instance variables are in the Y position), and it is not an array component. An array component would be the 10 slots I create with the statement new SomeType[10]. That array will have 10 slots and each slot will get the default value as stated in the list (so, if SomeType is Object, it'd be 10x a null reference, if its int, you'd get 10 zeroes, and so on).

And then lists what that default value is. For reference types, it's indeed null. But that's not relevant here because the list doesn't even apply to this situation.

What happens in class Runner when I declare int[] c? Shouldn't c "point" to null?

WARNING: This is highly technical information; akin to asking the details of how a carburetor works in a car. If your aim is to learn to drive a car, you don't need to know this stuff. If this goes over your head, let it - it's not too important, and written here to slake your curiosity only.

fields ('class variables' and 'instance variables') compile pretty cleanly to bytecode. But local variables do not. They aren't compiled one-to-one at all. Instead the compiler will just use a concept called slots.

The point is, the compiler simply cannot compile an attempt to access c before guaranteeing that c has been written. c has no value at all, not even null, until you assign it. If you tried to directly craft a class file with code that tries to read a slot before it was assigned, what would happen is that you'd be reading some dregs of data that was there before (reading uninitialized memory. Which isn't zeroes: It's whatever was there before). This is a security leak, of course. Maybe there's a segment of a password or key there, for example. This is why the class verifier will check if a class file that is about to be loaded contains code that could read uninitialized memory, and if it finds it, refuses to load it.

So, if you want to truly 'observe' what would happen, you need to [A] hack javac to stop refusing to compile your attempt to 'read' c before assigning to it, and [B] execute your class file with java by telling java to disable its class verifier. And then you'd read seemingly arbitrary values.

Local variables exist on the stack. That's just a chunk of memory, along with a pointer somewhere in the middle stating: This is the current 'head' of our stack. Whenever you need a variable, you just take the space you need for it by incrementing that 'head of stack' pointer. Conveniently, when you call a method you just use the same stack - methods know to never 'decrement' that pointer any more than where it was when the method was called (as you'd then be in memory space used by your caller).

When a method returns it just restores that pointer to the value it was when it was called (and if the method has a return type, pushes the returned value on top of the stack, so that the caller method can do something with it). The memory is not cleared. Clearing memory takes time. Why waste it?

Hence, when you would declare a local variable (which lives on this stack) , the system just increments the stack pointer and remembers that 'variable c' refers to 'this exact location on the stack'. It doesn't actually write anything to the space reserved this way.

Thus if you were to read it before writing to it, you'd see whatever was there from some previous method call. Except, you can't do that, because javac will refuse to compile code that would do that, and even if you recompile javac and remove that check, the JVM would refuse to run the class file.

March 31, 2026 Score: 5 Rep: 202,084 Quality: Medium Completeness: 80%

The answer is (a). Arrays are reference types. Local variables aren't class or instance variables. Those are handled differently. That is to say,

public static void main(String[] args) {
    Object obj;
    System.out.println(obj);
}

would also give you the error "variable obj might not have been initialized". This is explained at JLS-4.12.5 which says (in part):

Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2)

...

A local variable declared by a statement (§14.4.2, §14.14.1, §14.14.2, §14.20.3) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified using the rules for definite assignment (§16 (Definite Assignment)).

A local variable declared by a pattern (§14.30.1) is initialized implicitly, by the process of pattern matching (§14.30.2).

March 31, 2026 Score: 2 Rep: 1,191 Quality: Low Completeness: 60%

The answers from rzwitserloot and Elliott Frisch are great, but, I think that for a newcomer, they are too technical, so I am going to try to do my bit.

The first thing you should know is that when you create an object, all of its attributes are initialized to a default value, and this happens before the constructor method is executed, you can verify it in the following code:

public class MyClass  {

Integer a; int b; A c; int d[];

public MyClass() { System.out.println( a ); System.out.println( b ); System.out.println( c ); System.out.println( d ); }

class A { public String toSAtring() { return "class A"; } }

public static void main( String[] args ) { new MyClass(); } }

When you run this code, the console will display:

null
0
null
null

Now to understand what happens in your code, we need to reread the text that precedes it, and focus on a word "attributes", is the keyword, only the attributes of the class are initialized to their default value (these are the variables declared in the "body" of the class), but the variables created within methods, they are not instantiated, and you can verify it with the following code:

public class MyClass  {

public MyClass() { Integer e; int f; A g; int h[]; // System.out.println( e ); // System.out.println( f ); // System.out.println( g ); // System.out.println( h ); }

class A { public String toSAtring() { return "class A"; } }

public static void main( String[] args ) { new MyClass(); } }

If you remove // from any of the lines containing the System.out.println();, the "dreaded message" one will appear in your console:

Exception in thread "main" java.lang.RuntimeException: Uncompilable code - variable e might not have been initialized