Most useful programming languages allow data items to be written and read in arbitrary sequences, such that it will often not be possible to statically determine the order in which reads and writes will occur before a program is run. There are many cases where code will in fact store useful data into every slot before reading it, but where proving that would be difficult. Thus, it will often be necessary to run programs where it would be at least theoretically possible for code to attempt to read something which has not yet been written with a useful value. Whether or not it is legal for code to do so, there's no general way to stop code from making the attempt. The only question is what should happen when that occurs.

Different languages and systems take different approaches.

One approach would be to say that any attempt to read something that has not been written will trigger an immediate error.

A second approach is to require code to supply some value in every location before it would be possible to read it, even if there would be no way for the stored value to be semantically useful.

A third approach is to simply ignore the problem and let whatever would happen "naturally" just happen.

A fourth approach is to say that every type must have a default value, and any slot which has not been written with anything else will default to that value.

Approach #4 is vastly safer than approaach #3, and is in general cheaper than approaches #1 and #2. That then leaves the question of what the default value should be for a reference type. For immutable reference types, it would in many cases make sense to define a default instance, and say that the default for any variable of that type should be a reference to that instance. For mutable reference types, however, that wouldn't be very helpful. If an attempt is made to use a mutable reference type before it has been written, there generally isn't any safe course of action except to trap at the point of attempted use.

Semantically speaking, if one has an array customers of type Customer[20] , and one attempts Customer[4].GiveMoney(23) without having stored anything to Customer[4] , execution is going to have to trap. One could argue that an attempt to read Customer[4] should trap immediately, rather than waiting until code attempts to GiveMoney , but there are enough cases where it's useful to read a slot, find out that it doesn't hold a value, and then make use of that information, that having the read attempt itself fail would often be a major nuisance.

Some languages allow one to specify that certain variables should never contain null, and any attempt to store a null should trigger an immediate trap. That is a useful feature. In general, though, any language which allows programmers to create arrays of references will either have to allow for the possibility of null array elements, or else force the initialization of array elements to data which cannot possibly be meaningful.