2009-05-13 4 views
1

Во-первых, я не парень Java, но я столкнулся с тем, что появляется на поверхности, чтобы быть несогласованностью с тем, как работают импорт.реализация импорта

Скажет у вас есть файл, и в этом файле у вас есть основные функции, и вы также определили класс Foo, теперь другую реализацию Foo также существует в пакете. Предположим, вы хотите использовать обе версии в своей функциональности.

Вы не можете явно импортировать Foo из своего пакета, то есть import mypackage.Foo;

Так как это приведет к конфликту с классом, определенным локально в файле, поэтому при компиляции создается ошибка.

Что вы можете сделать импорт всей упаковки, то есть импорт mypackage. *;

Это будет работать, и вы можете получить доступ к Foo, используя полное имя, используя простое имя приведет к использованию локальной Foo. Несогласованность, которую я вижу, заключается в том, что, хотя первая генерирует ошибку (вы импортировали класс, а единственная цель импорта - использовать простое имя, а не полное имя), последнее не приводит к предупреждение.

Я бы подумал, что оба случая будут генерировать предупреждение, т. Е. Вы можете использовать неправильный класс, поскольку он определен в 2-х местах, или оператор import избыточен, поскольку использование простого имени будет разрешено локально определенному классу , а не импортированный.

Так что мой вопрос: есть ли основная причина, по которой он реализован таким образом?

Да, это случай с нарушением, я это понимаю.

+1

небольшое примечание: инструкция import используется только для того, чтобы вы не вводили имя пакета, оно ничего не делает, это просто ярлык. Если вы всегда используете полное имя, вам совсем не нужен импорт. –

+0

Я понимаю, почему существуют пакеты, это только то, что кажется непоследовательным, чтобы иметь возможность ссылаться на класс в импортированном пакете и не иметь никаких предупреждений вообще - независимо от того, определяется ли класс с этим именем локально или нет - все же есть ошибка когда вы явно пытаетесь импортировать класс с тем же именем, что и локальный. В обоих случаях оператор import избыточен для этого класса, но один дает и ошибку, а другой ничего не делает. – Stinomus

ответ

9

Вы можете получить доступ к Foo, используя полное имя, даже не импортируя mypackage. *;

О предупреждениях: Наверное, ничего опасного не происходит. Вы не используете ничего двусмысленного.

+0

В последнем примере локально определенный класс имеет молчаливое предпочтение - вы ожидаете, что поведение предыдущего примера будет соответствовать этому, поскольку в обоих случаях импорт является избыточным. – Stinomus

+0

Если будет предупреждение об неиспользованном/избыточном импорте, все компиляции будут печально спамить сотни предупреждений. А теперь никто не пишет импорт вручную. – alamar

+0

Ну, неиспользуемые и избыточные не совсем то же самое. Есть ли много случаев, когда вы импортируете пакет, в котором есть класс, который является тем же именем, что и один из ваших локально определенных классов? – Stinomus

1

импорт mypackage. * Может потребоваться для всего остального, что есть в mypackage. Если бы было предупреждение, было бы трудно избежать его вообще, т. Е. Вам пришлось бы полностью квалифицировать все другие классы и т. Д., Которые вы используете из mypackage. Хуже того, рассмотрим случай, когда версия 1 mypackage не содержит Foo, поэтому не было конфликта и, следовательно, вообще не было причины выпустить предупреждение. Версия 2 содержит Foo, но, конечно же, это не Foo, к которому вы хотите получить доступ в своей программе. Поэтому, если компилятор предупреждает о конфликтах «import package. *», Он делает «импортный пакет. *» Потенциально менее восходящим.

3

Как сказано выше, импорт фактически ничего не делает относительно Foo в другом пакете; независимо от того, импортируете ли вы или нет, вы не можете ссылаться на это другое Foo через короткое имя класса, и вы можете указать через его полное имя.

Концептуально вы можете думать о import mypackage.* не обязательно как «импортировать все классы из mypackage», но, возможно, «импортировать все не конфликтующие классы из mypackage». Я не знаю, как это делает реализация компилятора Sun, но она может определенно решить не соответствовать mypackage.Foo как часть шаблона (и, следовательно, не импортировать его вообще), и код будет работать одинаково в любом случае.

Импорт действительно просто устанавливает псевдоним от имени короткого класса до полностью квалифицированного имени класса (например, когда я говорю Date, интерпретируйте это как java.util.Date). Следует ожидать, что вы получите предупреждение, если вы сделаете что-то совершенно избыточное, например, импортировать только конфликтный класс. Однако, если вы потянете целый пакет с *, мне будет неловко, если бы компилятор пожаловался, что одно из столкновений классов; это было бы так часто на практике, и было бы безобидно 99% + времени, что это породило синдром «мальчик, который плакал волка» до такой степени, что вы вряд ли обратили бы внимание на эти и другие предупреждения, поскольку вы просто привыкайте к тому, чтобы их бомбардировали.

Кстати, если вы импортируете как java.util.*, так и java.sql.*, это разрешено и само по себе не приводит к каким-либо предупреждениям; но если вы попытаетесь обратиться к Date (без такого класса в вашем локальном пакете), вы получите ошибку компиляции, так как имя будет неоднозначным.

+2

JVM ничего не делает с импортом; внутренне он всегда использует полностью квалифицированные имена классов. Импорт относится только к компилятору. –

+2

Импорт в основном относится к разработчику, потому что, импортируя класс, вы можете ссылаться на него по его короткому имени и сохранять себя набирать. – duffymo

+0

Есть ли причина, по которой они не должны приводить к одному и тому же поведению? – Stinomus

1

Вы можете думать о «import p. *» Как о значении «когда вы не можете разрешить имя в текущем файле, попробуйте разрешить его в пакете p». Компилятор не импортирует все в p в точке, где он видит оператор импорта. Вместо этого он выглядит в p (и другие пакеты, названные в операциях import ... *), когда он находит имя, которое он не может решить в непосредственном блоке компиляции.

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

  • Нет связанных вопросов^_^