Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of automatically imported packages and ambiguity

Tags:

java

import

jls

JLS: Chapter 7. Packages:

A package consists of a number of compilation units (§7.3). A compilation unit automatically has access to all types declared in its package and also automatically imports all of the public types declared in the predefined package java.lang.

Lets assume the following code:

package com.example.p1;
public class MyClass { }
package com.example;
public class MyClass { }
package com.example;
public class String { }
package com.example;

import com.example.p1.*;

public class MainNameClash {
   private String s;    // No Error, even though ambiguous with java.lang.String!
   private MyClass m;   // No error, even though ambiguous with com.example.p1.MyClass!
}

If I move MyClass from com.example into com.example.p2 and import it with import com.example.p2.*, I get Error: the type MyClass is ambigious at the place where it is used.

It seems that the Types from the package itself always have precedence over any other imported types, be it automatically from java.lang or be it explicitly with a wildcard import, and that the compiler does not emit any warning or error.

Question:

  • Why does the java compiler not emit an ambiguity error in this case?
  • Where in the JLS is this behavior defined?
like image 417
Andreas Fester Avatar asked Jan 31 '14 10:01

Andreas Fester


1 Answers

The import statements of the form:

import packageName.subPackage.*

is Type-Import-on-Demand Declarations. i.e, the classes or any types from them will be imported only when that type is not available in the scope of current compilation unit.

From example 7.5.2-1 of that JLS section only:

The declaration might be shadowed by a single-type-import declaration of a type whose simple name is Vector; by a type named Vector and declared in the package to which the compilation unit belongs; or any nested classes or interfaces.

So, if you have a class String in the same package as your class, then using String in that class, will refer to your class, as java.lang.String will not be imported. It will only be imported on demand, as shown in example 6.4.1-2 of JLS § 6.4.1 - Shadowing.

like image 134
Rohit Jain Avatar answered Sep 19 '22 12:09

Rohit Jain