Why is import of class not needed when calling method on instance (Java)

前端 未结 5 973
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-17 15:37

Something that\'s confused me - an example:

Thing.java:

import java.util.Date; 

class Thing { 
    static Date getDate() {return new Date();}
}


        
相关标签:
5条回答
  • 2020-12-17 15:54

    Importing in Java is only necessary so the compiler knows what a Date is if you type

    Date date = new Date();
    

    Importing is not like #include in C/C++; all types on the classpath are available, but you import them just to keep from having to write the fully qualified name. And in this case, it's unnecessary.

    0 讨论(0)
  • 2020-12-17 15:54

    Are Thing and TestUsesThing in the same package? If so then you don't have to import Thing. The reason you have to import Date is because it's in a different package.

    0 讨论(0)
  • 2020-12-17 16:01

    Good question !!

    I think the result is the difference between how java compiler handles expressions vs statements.

    Date d = new Date(); // a statement
    

    where as

    new Thing().getDate().getTime()
    

    is an expression as it occurs inside println method call. When you call getDate on new Thing() the compiler tries to handle the expression by looking at the type info for Thing class, which is where it gets the declaration of type Date. But when you try to use Date separately in a statement like

    Date d = new Thing().getDate();
    

    you are assigning the result to a type in the current scope (class TestUsesThing ), compiler tries to resolve the type within that scope. As a result, you see the compiler error for unknown type.

    0 讨论(0)
  • 2020-12-17 16:10

    import statements are used for couple of things.

    1. Compiler type checking and avoid naming collision.
    2. Ensures byte code linkage

    Whenever we say

    System.out.println( new Thing().getDate().getTime() )
    

    The compiler parses this statement left to right and gets into that class.

    First level compiler parsing.

    1. Go to thing class
    2. compile doesn't have any linkage or ClassVersion error from Thing.class

    3. Check Thing.class has getDate method.
    4. if #3 is good then compiler pointer is still in Thing.class (which has date import statements) and I could invoke Time method.
    5. As a consumer TestUsesThing gets only long variable.

      System.out.println( new Thing().getDate() )
      

      5.1 In this case we are implicitly accessing .toString() method

    0 讨论(0)
  • 2020-12-17 16:11

    Actually, that was an ideal example, since there's two different standard Java Date classes: java.util.Date and java.sql.Date.

    How does it know which one to use? Simple. The getDate() method is declared as part of the definition of the Thing class, and part of that declaration is its returntype:

    public java.util.Date getDate() {
      return this.date;
    }
    

    Of course, if you have an import in the definition of the Thing class - and it's not ambiguous, you simply say:

    public Date getDate() {
    

    If you were to decode the binary of the Thing class, you'd see the method signature of the getDate method, and it includes the fully-qualified class name (including package) of the return type.

    An import is simply a way of telling the compiler what package(s) you want to assume when referring to classes without explicit qualifications. The list of imports will be scanned whenever an unqualified class name is seen, and the packages will be searched. If there's no ambiguity (such as importing both java.util.date and java.sql.Date), that class will be used. If you can determine the class implicitly, or if the class name is fully qualified, you don't need to import.

    0 讨论(0)
提交回复
热议问题