осуществление импорта - PullRequest
1 голос
/ 13 мая 2009

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

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

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

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

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

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

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

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

Да, это случай выброса, я это понимаю.

Ответы [ 4 ]

9 голосов
/ 13 мая 2009

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

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

3 голосов
/ 13 мая 2009

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

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

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

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

1 голос
/ 13 мая 2009

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

1 голос
/ 13 мая 2009

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

...