Home > other >  Inconsistent behavior between Eclipse compiler and javac command
Inconsistent behavior between Eclipse compiler and javac command

Time:01-18

Recently I'm testing java generic feature. Here is the testing code:

package test;

public class GenericAndMethodSignature {

    public static void main(String[] args) {
        (new ClazzAAA()).fooo();
    }

    public abstract static class ClazzAA<T> {

        public final void fooo() {
            System.out.println(this.foo((T) null));
        }

        public abstract String foo(T input);

        public final String foo(Integer input) {
            return "foo";
        }

    }

    public static class ClazzAAA extends ClazzAA<Integer> {
    }
}

If I compile and run it with Eclipse, console will show:

Exception in thread "main" java.lang.AbstractMethodError: test.GenericAndMethodSignature$ClazzAA.foo(Ljava/lang/Object;)Ljava/lang/String;
    at test.GenericAndMethodSignature$ClazzAA.fooo(GenericAndMethodSignature.java:12)
    at test.GenericAndMethodSignature.main(GenericAndMethodSignature.java:6)

However, if I compile it with javac command:

javac test/GenericAndMethodSignature.java

and run it with command

java test.GenericAndMethodSignature

The terminal will show "foo" successfully.

Also, an interesting thing, if I run the class compiled by eclipse with java command, I will get java.lang.AbstractMethodError too.

I use java byte code editor to check those two class, and find ClazzAAA compiled by javac overrides the generic method while class compiled by eclipse not.

Does anyone know why the behavior of these two compiler is different?

Not sure which result is correct.

CodePudding user response:

This is happening because Eclipse does not internally use javac: they have their own java compiler implementation built into Eclipse.

You can read about it here: CodeJava - Why does Eclipse use its own Java compiler?

Obviously, as you have discovered by yourself, the Java compiler that is built into Eclipse does not work in exactly the same way as javac; hence, there will be some discrepancies.

That was the answer to your question. What follows from here on is opinions.

Perhaps it made sense for eclipse to contain its own Java compiler back in the days of Java 1.3, when the language was still quite simple, or at any rate back in the days before Java started following a regular two-releases-per-year schedule. Nowadays, maintaining a java compiler implementation that faithfully emulates all of the complexity of javac and following up with new developments of javac that add more and more complexity once or twice a year is an untenable proposition.

Eclipse should not be trying to do this. It keeps trying to do this because not only it is 30 years old, but in many ways it is also stuck 30 years in the past.

I know you did not ask for it, but here is my recommendation on how you could avoid this problem:

Switch to a decent IDE.

That would be IntelliJ IDEA. IntelliJ IDEA uses Javac. They only use their own built-in parser for syntax highlighting and error underlining, so in the rare event that there is a discrepancy between their own parser and javac, it will only affect visual aspects of editing, it will never affect the actual code which gets generated and which is then run, and debugged.

  • Related