why does this code compile with eclipse compiler b

2019-03-20 02:30发布

问题:

There are a bunch of questions like this. I went through most of them but none actually but I couldn't come up with any answer:

I have a weird problem in one of my GWT/GWTP classes.
The class compiles fine with the Eclipse compiler but fails with the javac compiler (Maven).

//additional imports
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.View;

public class MyPresenter extends PresenterWidget<MyPresenter.MyView> {

    public interface MyView extends View {


    }

    some code
}

When i try to compile with maven I get following error:

cannot find symbol symbol: class View

View refers to the View interface in the com.gwtplatform.mvp.client package.

I have other classes which look the same and work fine.
The weird thing is that if I change the order of the imports or I specify the exact package of the View interface it compiles without any problems in maven.
To be specific I moved the import for com.gwtplatform.mvp.client.View

import com.gwtplatform.mvp.client.View;
//additional imports
import com.gwtplatform.mvp.client.PresenterWidget;

I had a similar problem some time ago with cyclic inheritance problem between classes which refer to inner classes (worked in eclipse but didn't in javac). However I am not sure if that is the same problem.

回答1:

Eclipse's compiler is actually a different compiler than the javac compiler. Sometimes they drift apart in behavior, usually they reconcile quickly.

This was very noticable when Java's generics came out. There were cases where eclipse either found fault with a generics directive that javac would permit or javac found fault with generics that eclipse would permit (can't remember which way it drifted apart, too long ago). In either case, javac is more likely to be the correct implementation.

In your case, you pollute the namespace with your generics reference to an inner class. Odds are that eclipse is reaching for the "View" in a different priority order than javac. Odds are excellent that either Javac implements the order as it is specified in the Java language guidelines, or the Java guidelines have not yet pronounced the "one true order" of resolving conflicting like-named classes. Normally this is not a problem because it is not permissible to use the same non-fully-qualified name in Java twice; however, with internal classes the specifications can be sort of "worked around".

I would make the

public interface MyView extends View {


}

bind to just one view (don't know if com.gwtplatform.mvp.client.View or MyPresenter.View is the right one) by making the name explicit.

public interface MyView extends MyPresenter.View {


}

or

public interface MyView extends com.gwtplatform.mvp.client.View {


}

That way you don't fall victim to the interface "binding" to the wrong type in a compiler-dependent manner.