Issue
I usually work with IntelliJ but recently one of my team mate opened project in eclipse and he found eclipse showing error Type mismatch: cannot convert from Object to boolean
in 2 separate java files. I crossed checked in IntelliJ but no error.
Below are the screenshot from Eclipse and IntelliJ respectively:
Eclipse:
IntelliJ
I also checked that both the IDEs have same compiler compliance level, i.e. 11
Eclipse:
IntelliJ
Even though Eclipse is showing error, if I run the project in eclipse then build and run is successful.
As in above actual code example row
object is created from an interface, I do not have access to see it's actual implementation. Hence just to generate the scenario so that I can understand why and how two different IDEs behave differently ? I have created below reproducible example:
IRow.java:
public interface IRow {
<T> T getValue();
}
RowImpl.java
public class RowImpl implements IRow {
@SuppressWarnings("unchecked")
@Override
public <T> T getValue() {
return (T) Boolean.TRUE;
}
}
and the main.java
public class main {
public static void main(String args[])
{
IRow row = new RowImpl();
if(row.getValue()) //--> Eclipse shows error but IntelliJ not
System.out.println("value is true");
}
}
Solution
Eclipse uses its own compiler, distinct from javac, and this error appears to be the manifestation of a difference in compiler implementation.
This is the ticket raised on their issue tracker. https://bugs.eclipse.org/bugs/show_bug.cgi?id=513766
Eclipse compiler devs seem to consider it a bug in javac, rather than the other way around. So perhaps the question should be "why does javac accept it"? This ticket exists for the JDK https://bugs.openjdk.org/browse/JDK-8179483, and was raised by Dan Smith who is a language designer at Oracle. He states that "javac should reject this program".
That said, I'd be quite surprised if they remove this "feature". Oracle are not in the habit of making backwards-incompatible changes, which this would be for people like you. A more likely solution seems an adjustment to the spec to allow for it, but I'd bet it's more complex than it seems on the surface, or they might have addressed it by now.
I think effectively this behaviour is ambiguously defined, and you should ideally avoid relying on it. I'd change your code to
if(Boolean.TRUE.equals(row.getValue()))
Answered By - Michael
Answer Checked By - Cary Denson (JavaFixing Admin)