Nico
Nico

Reputation: 2663

Why does automatic boxing work in eclipse but not in javac?

This code:

Integer ints[] = new Integer[]{'1', '2', '3'};

compiles just fine in eclipse, but javac (both version 1.6.0_27 and 1.7.0) gives the following error:

BoxTest.java:4: incompatible types
found   : char
required: java.lang.Integer
               Integer ints[] = new Integer[]{'1', '2', '3'};

BoxTest.java:4: incompatible types

Why?

I assume it's some kind of compiler flag, but digging trough eclipse to figure it out is not exactly straight forward.

Upvotes: 18

Views: 772

Answers (6)

Ayushman
Ayushman

Reputation: 272

I found a lot of confusion on this thread on how Eclipse compiles Java code. Here's the deal - Eclipse uses its "own" JDT compiler, which has nothing to do with either Sun or Sun's(now Oracle's) javac compiler. It is an independently developed compiler, licensed under EPL, and follows the JLS, just as javac does. So whatever does/does not compile with javac, does/does not compile with Eclipse JDT.

That said, the problem reported here looks like a bug in the Eclipse compiler. https://bugs.eclipse.org/bugs/show_bug.cgi?id=362279

Upvotes: 2

A.H.
A.H.

Reputation: 66273

As already noted by stivlo the Eclipse JDT compiler silently treats the code like this:

Integer refI = Integer.valueOf((int)'a');

But the Java Language Specification says in chapter 5.2 (emphasis mine):

Assignment conversion occurs when the value of an expression is assigned (§15.26) to a variable: the type of the expression must be converted to the type of the variable. Assignment contexts allow the use of one of the following:

* an identity conversion (§5.1.1)
* a widening primitive conversion (§5.1.2)
* a widening reference conversion (§5.1.5)
* a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
* an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

The (int) 'a' cast is the first conversion, the Integer.valueOf(int) is the second conversion. The javac compiler enforces the rules by allowing only one conversion.

So it seems, you have found a bug in the Eclipse JDT compiler.

Upvotes: 4

paulsm4
paulsm4

Reputation: 121759

Actually, the Eclipse IDE makes use of Java @SuppressWarnings:

http://knol.google.com/k/suppresswarnings-annotation-in-java#

The moral equivalent from javac are the XList:xxx options:

http://download.oracle.com/javase/1,5.0/docs/tooldocs/windows/javac.html#options

ADDENDUM:

  1. Eclipse uses the standard JDK, of which javac is a part.

  2. Part of the difference can be accounted for by Eclipse's internal use of (what other languages sometimes call "pragmas"), such as @sSuppressWarnings.

  3. The MAIN difference, however, is that Eclipse uses the JDT libraries, which sit UNDER the javac executable.

  4. Here's an excellent discussion:

'Hope that helps .. PSM

Upvotes: 0

stivlo
stivlo

Reputation: 85506

What javac is not doing, is not autoboxing, but is an automatic cast. In javac it compiles with:

Integer ints[] = new Integer[] { (int) '1', (int) '2', (int) '3' };

The same happens with just one Integer, again in javac, I've to do the explicit cast to compile:

Integer a = (int) '1';

But here is what I found. Using Eclipse JDT batch compiler from the command line it works, even without the casts:

$ java -jar org.eclipse.jdt.core_3.7.1.v_B76_R37x.jar -classpath rt.jar \
  -1.6 Appo.java 

I've looked at the options of javac and I don't think there is any way to change this behaviour.

I've to infer that the difference is caused by the fact that Eclipse is not using javac internally, but the JDT compiler.

Upvotes: 6

manuzhang
manuzhang

Reputation: 3025

Window -> Preference -> Compiler -> Errors/Warning -> Potential programming problems -> Boxing and unboxing conversions; set the value to Error

Upvotes: 1

PDStat
PDStat

Reputation: 5835

Possibly the -source flag set to a pre auto boxing version of Java? for example

javac -source 1.4 BoxTest.java

Upvotes: 0

Related Questions