15

I wrote this line of code in Eclipse Mars for messing purposes:

null.toString();

And I got the following compiler error message:

Cannot invoke toString() on the primitive type null

Which is very strange since null is not a primitive type nor an object reference as explained here: Is null an Object?

So, just to be sure, I tried to compile such odd line of code using javac and I got this result:

NullTest.java:3: <nulltype> cannot be dereferenced

   null.toString();
       ^  
1 error

Does somebody know why Eclipse would give such (IMO) misleading compiler error message?

Lii
  • 11,553
  • 8
  • 64
  • 88
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • I get the same "primitive" error message in Kepler and Luna, too, so it's not a new thing. – azurefrog Nov 05 '15 at 15:20
  • 2
    Sounds like an evaluation path error in ECJ. File a bug on it, which they'll ignore until Java is replaced by another language. – chrylis -cautiouslyoptimistic- Nov 05 '15 at 15:20
  • [Yeah, smells like a bug to me, too.](http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/4.2/org.eclipse.jdt/ui/3.8.0/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/types/TypeEnvironment.java#TypeEnvironment.0NULL) It's been around for a long while though. – Makoto Nov 05 '15 at 15:24

2 Answers2

6

Since the null-type is a subtype of Object, it's conceivably OK to invoke Object methods on null.

However, following that logic, since the null-type is a subtype of every reference type, we should be allowed to invoke any method of any class/interface on null. That'll be a mess.

Syntactically, null.toString() should be recognized as a method invocation expression at first, because null is a Primary expression. Then, to determine the class/interface to search for the method toString, JLS says

...The class or interface to search is T if T is a class or interface type, or the upper bound of T if T is a type variable

It is a compile-time error if T is not a reference type.

T is the null-type here; it is not a class type, interface type, or type variable, therefore this step should fail. However, does it fail because T is not a reference type?

Is the null-type a reference type? JLS says

The types ... are divided into two categories: primitive types and reference types

The numeric types are ....

The reference types are class types, interface types, [type variables,] and array types . [period!]

There is also a special null type.

Depending on your parsing of the text, null-type may or may not be a reference type. That is usually not really important; it's just a matter of categorization. But it leads to confusions, for example in this case -- the failure is because T is not a "proper" reference type, and the compiler deduces by mistake that it must be a primitive type then.

Community
  • 1
  • 1
ZhongYu
  • 19,446
  • 5
  • 33
  • 61
  • I think this is something Scala has done right. The Option class. Contains null or something or valid. – Totoro Nov 05 '15 at 17:16
  • @Totoro if you refer to [`Option`](http://www.scala-lang.org/api/current/index.html#scala.Option), well there's a similar type called [`Optional`](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html). – Luiggi Mendoza Nov 05 '15 at 17:20
  • This explanation seems more interesting and convincing for me. At least, it makes me think that Eclipse guys *forgot* that there's a null type and just assumed that if the variable is not a reference then it's a primitive and let it be. Bugs or assumptions like this happen even in the most experienced teams. – Luiggi Mendoza Nov 05 '15 at 17:22
  • @LuiggiMendoza - I think the more reasonable choice is to consider null-type a reference type; I bet most people think in that way; and the JLS probably has many places where that is implied. – ZhongYu Nov 05 '15 at 17:25
  • I don't think it's a correct reading of the spec to say that `null` is a subtype of `Object`. It's a special type, whose reference is castable to any other reference type -- but the spec doesn't ever say that it's a subtype of object. In fact, 4.3.1 describes it as "a special null reference, which refers to no object." The absence of an object is not a subtype of an object. – yshavit Nov 05 '15 at 18:40
  • 1
    @yshavit -- 4.10 does say that null-type is a subtype of every type (even including primitive type? probably a bug there). The spec is very chaotic on null. I think it mixes up lots of different concepts together (to be more concise?) - empty type, null type (with one value - null), strict class/interface type (with object values; no null), loose reference type. – ZhongYu Nov 05 '15 at 18:56
  • Say we use `!String` notation for "strict" reference type; the type does not include `null` value. The usual `String` type is actually a loose type, equivalent to `!String or null-type`; that is why `String` accepts `null` value, and null-type is a subtype of `String` – ZhongYu Nov 05 '15 at 18:58
  • however, in `obj instanceof String` expression, `String` is used in a strict sense, and the expression is false if `obj` is null – ZhongYu Nov 05 '15 at 19:01
  • Yeah, good point -- I missed that one sentence there. And yes, it's oddly hand-wavy about null. It's not even quite sure as to whether null is a reference type or some other, third type, which is weirdly castable to a reference type. – yshavit Nov 05 '15 at 21:27
-2

There is no reason.

Usually eclipse analyze the bytecode and for some reason null.toString() are two bytecode-statements, a definition and a call. Because you can call toString only on objects, eclipse assumes the declaraion must declare a primitive.

You can write a Bugreport but think about the overhead that may come with the internationalization of the error-message.

Grim
  • 1,938
  • 10
  • 56
  • 123
  • 2
    If you talk about internationalization of the error message, I must say they're providing a misleading error message in several languages, not only in English! – Luiggi Mendoza Nov 05 '15 at 15:34
  • But its a new message that does not exists in any other language till now. Its scut-work vs nonscientific. – Grim Nov 05 '15 at 15:38
  • Eclipse does not analyze the bytecode: it is its own compiler which analyzes the source code building the AST, then *produces* the bytecode. So your answer is misleading. – Tagir Valeev Jan 13 '16 at 05:30