The basic concept of a reference in C++ is that it is an alternate name for an object. It is therefore not possible to have a null reference, as having an alternate name for something non-existant is meaningless. All the names refer to nothing.
One consequence of this concept, which allows plenty of optimisations by the compiler, is that a reference is assumed to refer to something that exists, IF it is used. For example, the compiler is not required to add runtime checks to ensure a reference is valid - it is assumed to be valid, so doesn't need to be checked. That is the case because any act that creates an invalid reference (eg a null reference, a dangling reference) is specified to have undefined behaviour. If the act of creating something is undefined, the result of using it is also undefined.
A pointer, on the other hand, is something that optionally contains the address of an object. This means a pointer may be NULL, indicating it points at no object. Dereferencing such a pointer is, in itself, undefined behaviour (and, since creating a null reference requires dereferencing a null pointer, that explains why creating a null reference gives undefined behaviour - let alone using that null reference). The difference is that the programmer can check if a pointer is null before dereferencing it, and hence avoid that form of undefined behaviour.
Because of this, a C++ reference is sometimes described as a glorified pointer. It is not. At most, it is a deliberately constrained pointer. The constraints can't eliminate programmer error (there is no upper bound on programmer stupidity, and there is always opportunity for a programmer to deliberately cause error) but they can help reduce programmer error.
The concepts of a reference in other languages are a bit different.
As laserlight noted, Java's concept of a reference has some attributes that, in C++, are only associated with pointers. In effect, it might be said, that the Java designers sought to publically eliminate pointers as an "unsafe construct" but then found they had to add to quietly implement some of those unsafe features into their reference type. A Java reference therefore allows more dangerous practices (i.e. opportunities for programmer error) than does a C++ reference. That's not an indictment of Java - it's simply a realistic result in programming language design when a marketing imperative ("we are creating a safer C++!!!!") intersects with pragmatics ("if something is too safe it can be unusable").
Had to read your post a couple times in order to have it sink in grumpy.
It's a very interesting conundrum to say the least, that languages who are so adamant about eliminating pointers, have to end up implementing them in the first place in order for the language to even work.
I guess I'll never understand marketing...