Reputation: 2663
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
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
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
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:
Eclipse uses the standard JDK, of which javac is a part.
Part of the difference can be accounted for by Eclipse's internal use of (what other languages sometimes call "pragmas"), such as @sSuppressWarnings.
The MAIN difference, however, is that Eclipse uses the JDT libraries, which sit UNDER the javac executable.
Here's an excellent discussion:
'Hope that helps .. PSM
Upvotes: 0
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
Reputation: 3025
Window -> Preference -> Compiler -> Errors/Warning -> Potential programming problems -> Boxing and unboxing conversions; set the value to Error
Upvotes: 1
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