3

So I ask myself why I don't have to import java.io.PrintStream to use System.out. I know that java.lang is imported by default by the compiler. Allright.

Because System is a class of java.lang I can use the field System.out. But this field has the type java.io.PrintStream and this class is not imported by default (it's in the java.io package), so why can i access System.out.print() for instance without importing java.io.PrintStream separately ?

If I create my own class MyClass then I cannot do something like this MyClass anInstance = new MyClass(); MyClass need first to be imported. Why is this not mandatory for the PrintStream?

Thanks in advance.

Jessica Tiberio
  • 137
  • 1
  • 9
Tri So
  • 33
  • 3
  • import statements are only a hint for the compiler. Unused imports are not actually linked and things that are referenced, such as `out`, a PrintStream will be linked by the compiler. – Ben May 23 '18 at 12:09
  • `out` is not a class, out is an instance of `PrintStream` in `System` class. Only those imports of types (classes / interfaces / annotations) are added which are used in the current class – Hemant Patel May 23 '18 at 12:09
  • You could e.g. totally call a method in some class returning an object of `MyClass` without having it imported. – Ben May 23 '18 at 12:10
  • I still don't understand, sry. Yes, out is an instance of PrintStream, but PrintStream is not imported so the structure is unknown, why does the compiler know where to find PrintStream etc.? The structure must be known, otherwise it makes no sense (i.e. in calling methods, fields, etc.). – Tri So May 23 '18 at 12:16

2 Answers2

5

You would only need to import PrintStream if you needed to use PrintStream (the class name) in your code. Using a field on another object which is of type PrintStream doesn't require it.

That is, import is to tell the compiler what PrintStream (the literal text) means in your code. It's not to tell the compiler that you'll use a PrintStream object you get from somewhere else (in this case, System).

Put it another way: import is about knowing how to compile the source text; it's not about what gets used at runtime. Imports are not written to class files, for instance; the information just isn't needed at runtime. Field and variable definitions are stored with their fully-qualified class names, not import-relative ones. Since out's type information in System says it's java.io.PrintStream, the compiler (and later, the JVM) knows it's a java.io.PrintStream, whether you import PrintStream in your code or not.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • It's because java.lang.System imports the PrintStream by itself? I understand this now. Thanks! – Tri So May 23 '18 at 12:27
  • 1
    @TriSo - No, not really. `import` is about knowing how to *compile* the source text. It's not about what gets used at runtime. So yes, `System.java` has an import for `PrintSream`, but that's so the compiler knows what `PrintStream` is in the `System.java` source text when compiling it (when they're building the JDK/JRE jars). Imports are not written to class files, for instance; the information just isn't needed at runtime. Fields and variables are stored with their fully-qualified class names, not import-relative ones. – T.J. Crowder May 23 '18 at 12:34
  • Ok, the import statement is just for the compiler so that i can use the unqualified name, for instance System instead of java.lang.System. Thus, it's kind of "renaming"? But i mean where gets the compilter the definition of PrintStream? It's probably more a linking/compiling topic? – Tri So May 23 '18 at 12:51
  • 1
    @TriSo - Name shortening, yes; not renaming. I just updated my answer in a way that may address that question (in the process of folding my comment above into the answer). At compile-time, when the compiler sees `System.out`, the default import of `java.lang` tells it that `System` is `java.lang.System`, so it looks up `out` in that class and sees that it's declared with the type `java.io.PrintStream`. So it uses that type to check the members (methods and such) you're using on `out`. `out`'s declared type is stored in `System.class` and used by the compiler and JVM. – T.J. Crowder May 23 '18 at 12:57
  • Ok, one last and final question. If i run for instance System.out.println("Test") in my Test.java file. First the compiler tells that this call is java.lang.System.out.println("Test") and looks up out as you already mentioned. After the compilation we have a Test.class file. The JVM now loads the Test.class file and sees java.lang.System.out.println("Test") and that out has the type java.io.PrintStream. Then, the JVM loads, links and initialize java.io.PrintStream class i.e. java.io.PrintStream.class. And then the JVM can call the println() method, is this right? – Tri So May 23 '18 at 13:12
  • @TriSo - Well, it will have already loaded it. The `System` class is loaded very early on, and its static fields are initialized, well before your code runs. – T.J. Crowder May 23 '18 at 13:15
  • But in general this is the way JVM works? If i use for instance something else instead of System. Thanks! I think i understand it now. – Tri So May 23 '18 at 13:19
  • @TriSo - Yes, for the most part, the JVM demand-loads classes the first time it needs them. That's usually because it's loaded another class and needs to load the classes for its fields, parameter types and return types, or because `Class.forName` is called. :-) – T.J. Crowder May 23 '18 at 13:43
0

X.java

package p;
import q.Y;
public class X { Y y; }

Z.java

import p.X;

... X x = ...;
... x.y ...;

For the occurrence of X the compiler needs the import of X.

For x.y the compiler can find in the class data of X the class Y for having the methods of Y and such.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • I understand this, so in translating this example to my case we can say that java.lang.System imports java.io.PrinterStream? – Tri So May 23 '18 at 12:23
  • No, the class only contains the class name of `PrintStream` and the call's signature of `PrintStream#println(String)`. The JVM/java executing the classes then "links" all together. – Joop Eggen May 23 '18 at 12:28