Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Eclipse compile this, but javac doesn't?

We have some unit tests which compile and run fine in Eclipse 3.4, but when we try to compile them using javac, it fails. I've managed to cut the code down to something small and self-contained, so it has no external dependencies. The code itself won't make much sense because it's all out of context, but that doesn't matter - I just need to find out why javac doesn't like this:

public class Test {

    public void test() {
        matchOn(someMatcher().with(anotherMatcher()));
    }

    void matchOn(SubMatcher matcher) {}

    SubMatcher someMatcher() {
        return new SubMatcher();
    }

    Matcher anotherMatcher() {
        return null;
    }
}

interface Matcher <U, T> {}

class BaseMatcher implements Matcher {
    public BaseMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher matcher) {
        return this;
    }
}

I've tried with JDK 1.5.0_10 and 1.6.0_13, with the same result:

Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to (test.BaseMatcher)
                matchOn(someMatcher().with(anotherMatcher()));
                ^
1 error

I think this is perfectly valid Java. The SubMatcher.with() method returns a more specific type than BaseMatcher.with(), but the compiler seems to think that the return type is BaseMatcher. However, it's possible that the Eclipse compiler is incorrectly allowing something it shouldn't be.

Any ideas?

like image 897
skaffman Avatar asked Jul 24 '09 10:07

skaffman


People also ask

Does Eclipse use javac?

Eclipse has its own built-in incremental compiler so it does not need (nor use) javac from a JDK. So yes, Eclipse's Java Development Tools (JDT) will function with only a JRE.

Why is my Java program not compiling?

It means that javac.exe executable file, which exists in bin directory of JDK installation folder is not added to PATH environment variable. You need to add JAVA_HOME/bin folder in your machine's PATH to solve this error. You cannot compile and run Java program until your add Java into your system's PATH variable.

What happens when you compile a Java program with the javac command or an IDE?

In Java, programs are not compiled into executable files; they are compiled into bytecode (as discussed earlier), which the JVM (Java Virtual Machine) then executes at runtime. Java source code is compiled into bytecode when we use the javac compiler. The bytecode gets saved on the disk with the file extension .

Does JVM contain javac?

No, javac isn't part of the JVM itself.


2 Answers

in BaseMatcher you need to specify type parameters:

public SubMatcher with(Matcher<?, ?> matcher) {

in order to allow javac to match your with method

PS

imho is a bug of eclipse compiler

like image 179
dfa Avatar answered Sep 18 '22 02:09

dfa


I made it build successfully by adding <?,?> to Matcher in SubMatcher.with:

class SubMatcher extends BaseMatcher {
    @Override
    public SubMatcher with(Matcher<?,?> matcher) {
        return this;
    }
}

Without this, the method signature is different from the base. I wonder whether there's a bug in the @Override checking that fails to notice this.

like image 26
Greg Hewgill Avatar answered Sep 19 '22 02:09

Greg Hewgill