5

I know I can include a class or collection of classes in my Java project using the import statement.

For example, import java.io.utils.* imports (i.e. makes available for use in my Java program) all the classes in the java.io.utils package.

My question is, do the classes in an imported package need to be compiled? Or can packages also include uncompiled Java files? If it can be either, when can we use class files and when can we use Java files?

Adam
  • 8,752
  • 12
  • 54
  • 96
  • 3
    You can't execute or reference uncompiled code. – shmosel Mar 02 '17 at 07:41
  • What are you `include`ing when you include a header file in C++ then? – Adam Mar 02 '17 at 07:41
  • 2
    Importing in Java is nothing like including in C. – shmosel Mar 02 '17 at 07:42
  • As for "you can't execute or reference uncompiled code", that makes sense. My thinking was that you could tell the compiler in an `import` statement where to get the source code that needs to be compiled in order to resolve a given dependency. Just a guess really, hence the question. – Adam Mar 02 '17 at 07:47
  • 3
    @shmosel: You certainly *can* refer to uncompiled code if the compiler knows where to find the source file. I'll add an example in my answer. – Jon Skeet Mar 02 '17 at 07:47
  • 1
    Read also ['import' in java vs. '#include' in C/C++](http://stackoverflow.com/questions/13517618/import-in-java-vs-include-in-c-c) – Thomas Fritsch Mar 02 '17 at 07:53
  • 1
    @JonSkeet Of course. I meant that compiled code can't reference uncompiled code. Which I understand to be what OP is asking about. – shmosel Mar 02 '17 at 08:09
  • Here's another good reference: http://stackoverflow.com/questions/1053658/how-is-import-done-in-java – Adam Mar 02 '17 at 08:24

3 Answers3

10

Import just means "make the imported classes available by their simple names" - you can remove imports entirely if you use fully-qualified names everywhere. It's definitely not like #include in C for example.

When you compile, if you try to refer to uncompiled code it will be compiled at that point, assuming the compiler can guess where to find the source code. The result never refers to uncompiled code, because the compiler needs to know what each type exposes.

As a complete example, construct the following file structure:

// src/foo/A.java
package foo;
import bar.*;

public class A {
    public static void main(String[] args) {
        B.sayHello();
    }
}

// src/bar/B.java
package bar;
public class B {
    public static void sayHello() {
        System.out.println("Hello");
    }
}

Then in the src directory, run:

javac foo/A.java

That will automatically compile bar/B.java - but wouldn't compile any other code that isn't referenced (potentially transitively).

I would strongly recommend against using this "compile on demand" behaviour anyway though - if you compile class A that depends on class B, it will compile B the first time, but after that if you change B and recompile A, the compiler won't recompile B. I would organize your code into appropriate projects, and always recompile a complete project at a time, adding a project's output directory to the classpath for a project that depends on it, rather than allowing compiling one project to recompile bits of another on demand.

(Note that this isn't talking about the incremental compilation that many IDEs support... that's a rather different matter, and is fine assuming it's been implemented properly.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    So `import` statements are simply labour-saving devices. Any class or package I reference in an `import` statement is already available for use because I've included the class/package on the classpath. If I wanted to avoid using `import` statements entirely I could just use fully qualified names. – Adam Mar 02 '17 at 08:05
4

Unlike C, import in Java does not "copy" stuff. Packages in Java is simply a way of avoiding ambiguity. javax.swing.Timer and java.utils.Timer are different Timers. When you say import javax.swing.Timer, you are telling the compiler that you mean javax.swing.Timer, not any other Timer.

All these things that you can import comes from the JDK or some other libraries you're using, or they are created by you. The classes that fall into the former category is already compiled (.class). The classes you created are compiled as well, when you do javac. You can't refer to any uncompiled classes. Since they are uncompiled, the computer does not know they exist.

The reason why your IDE knows your packages and classes before you compile your code is because IDEs are smart. They compile your code before you even notice it.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

As Java documentation reports.

You might have to set your CLASSPATH so that the compiler and the JVM can find the .class files for your types.

link: https://docs.oracle.com/javase/tutorial/java/package/summary-package.html

Giorgio Desideri
  • 169
  • 1
  • 12