Eugene Stepanenkov Eugene Stepanenkov - 1 month ago 8
Java Question

Why do I get different compilation result depending on java imports and static imports sequence order?

I've faced an issue with compilation, but cannot understand why it occurs.
Actually much time was spent to understand where the reason is (it was far from obvious in a "crap" project), but after reproducing that error I greatly simplifies all the code to show a little example especially for you:

Package structure:

com.company
|
----Main.class
|
----maker
|
----Maker.class


Maker.class

package com.company.maker;

public interface Maker {
}


Main.class

package com.company;

import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;
import com.company.maker.Maker;

public class Main {

public static void main(String[] args) {
System.out.println(STRATEGY1.name() + STRATEGY2.name());
}

static class MakerImpl implements Maker {
enum Strategy {
STRATEGY1, STRATEGY2
}
}
}


And I got compilation error in Main class:

Error:(15, 39) java: cannot find symbol
symbol: class Maker
location: class com.company.Main


And if I change the import sequence from

import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;
->import com.company.maker.Maker;


to

->import com.company.maker.Maker;
import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;


then it is compiled successfully.

Is it normal behaviour of Java Compiler? If so I want to clearly understand why it happens.

P.S. tested using java version 1.8.0_112 and 1.7.0_80 (MacOS)

Answer

check this :

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6391197

It seems that the compiler sees the first static import and then jumps to take care of your inner class, but fails because it did not read the last non static import.

So when you change the import order, this problem does not occur, since when the compiler reads the static import and jumps to take care of the inner class because those imports are used in the inner class, the compiler is happy since it already imported the non static Maker Interface.

Wich means that the imports are evaluated eagerly.

I hope this helps.