2014-01-31 3 views
5

JLS: Chapter 7. Packages:Порядок автоматически импортируемых пакетов и неоднозначность

Пакет состоит из нескольких единиц компиляции (§7.3). Модуль компиляции автоматически получает доступ ко всем типам, объявленным в его пакете, а также автоматически импортирует все общедоступные типы, объявленные в предопределенном пакете java.lang.

Давайте предположим, что следующий код:

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! 
} 

Если я перееду MyClass из com.example в com.example.p2 и импортируйте его с import com.example.p2.*, я получаю Error: the type MyClass is ambigious в том месте, где оно используется.

Похоже, что типы из самого пакета всегда имеют приоритет над любыми другими импортируемыми типами, будь то автоматически с java.lang или явно им с подстановочным импортом и что компилятор не выдаёт никаких предупреждений или ошибок.

Вопрос:

  • Почему Java компилятор не генерировать ошибку неоднозначности в этом случае?
  • Где в JLS это поведение определено?

ответ

7

Импортные утверждения вида:

import packageName.subPackage.* 

является Type-Import-on-Demand Declarations. то есть классы или любые типы из них будут импортированы только тогда, когда этот тип недоступен в области текущего блока компиляции.

Из примера 7.5.2-1 этого раздела JLS только:

Декларация может быть омрачены одного импорта типа декларации такого типа, простое имя Vector; по типу Vector и объявляется в пакете, к которому относится единица компиляции; или любые вложенные классы или интерфейсы.

Так что, если у вас есть класс String в том же пакете, классе, а затем с помощью String в этом классе, будет относиться к классу, так как java.lang.String не будут импортированы. Он будет импортироваться только по запросу , как показано в example 6.4.1-2 от JLS § 6.4.1 - Shadowing.

2

Я думаю, что это покрывает Shadowing & Obscuring тем, что класс с ограниченным пакетом имеет приоритет над подстановочным импортом.

0

На самом деле речь идет о простые имена типа:

6.5.5.1Простые имена типов Если имя типа состоит из одного идентификатора, то идентификатор должен происходить в рамках точно один видно объявление типа с этим

О объеме мы можем прочитать здесь:

(6.3) Объем заявления является областью программы, в течение которого сущности заявленной в декларации может быть отнесено к использованию простого имени, при условии, что видна

..

Область действия типа импортируемой декларацией одного импорта типа (§7.5.1) или декларация импорта типа по требованию (§7.5.2) это все класса и интерфейс тип d eclarations (§7.6) в блоке компиляции , в котором появляется объявление импорта, а также любые аннотации на объявления пакета (если есть) блока компиляции.

Смежные вопросы