Каков правильный стиль для импорта списка в Java?
Лучше ли перечислить каждый отдельный фрагмент пакета, который вам понадобится (см. № 1), или лучше просто импортировать все из пакета (см. № 2)?
1
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.ColorConvertOp;
2
import java.awt.*;
10 ответов
Это НЕ просто вопрос стиля; импорт по требованию может привести к тому, что код перестает компилироваться при добавлении новых классов в существующие пакеты.
Основная идея (см. http://javadude.com/articles/importondemandisevil.html.):
import java.awt.*;
import java.util.*;
...
List list;
работал в Java 1.1; Начиная с Java 1.2, приведенный выше код больше не будет компилироваться.
Импорт по требованию - ЗЛО, потому что ваша программа может перестать компилироваться, когда новые классы добавляются в существующие пакеты!
ВСЕГДА используйте явный импорт. Это не вопрос стиля; это вопрос безопасности.
Это особенно плохо, если вы включаете идеально компилируемый код, а год спустя кто-то проверяет его и пытается скомпилировать с помощью новых библиотек классов.
(Импорт по требованию является примером действительно плохой функции языка программирования - никакая функция не должна нарушать код при добавлении новых типов в систему!)
Используйте импорт индивидуально.
Производственному коду гораздо удобнее перечислять все импортируемые классы.
Хотя IDE отлично справляются с задачей, помогая вам узнать, какие классы используются, легче понять, что вы имеете в виду:
java.util.List;
и не
java.awt.List;
и так далее.
Кроме того, рекомендуется группировать их по пакетам, начиная с основных библиотек, передаваемых сторонними разработчиками, и заканчивая собственными библиотеками проекта:
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.TableModelListener;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
import your.own.packagename.here.SomeClass;
import your.own.packagename.here.OtherClass;
Использование подстановочных знаков приемлемо для небольших самостоятельных проектов / классов. Это быстрее, но не ожидается, что будет ремонтопригодным. Если любой другой разработчик вовлечен, используйте первый.
Последний, как правило, считается "плохой формой". Благодаря поддержке инструментов нет оправдания тому, что они не перечислены по отдельности, и это устраняет любую неопределенность.
Имейте в виду, Eclipse по умолчанию использует подстановочные знаки для статического импорта, а явный импорт для обычных. Не уверен, почему это делает это различие.
edit: различие очевидно задним числом - статический импорт часто ссылается на статические методы, и вы не можете однозначно ссылаться на статический метод по имени (из-за перегрузки). Так что, если он не может быть полностью однозначным, вы можете использовать подстановочный знак.
Я знаю, что вопрос был не в производительности, а в вопросе о расходах на импорт в месяце на сайте http://www.javaperformancetuning.com/ вкратце объясняет, почему следует избегать использования подстановочных знаков:
(...) Наконец, многие люди находят, что использование импорта с подстановочными знаками делает исходный код гораздо менее читабельным, поскольку читателю также необходимо выяснить, из какого пакета поступает конкретный класс, а не просто искать его в операторе импорта.
Таким образом, полный ответ
- Использование оператора импорта не требует затрат времени выполнения
- Процесс компиляции может занять немного больше времени с оператором импорта
- Процесс компиляции может занять еще больше времени с помощью оператора подстановочного знака импорта
- Для улучшения читаемости операторы импорта с использованием подстановочных знаков являются плохой практикой для всего, кроме одноразовых классов
- Затраты на компиляцию операторов импорта без подстановочных знаков незначительны, но они дают преимущества читабельности, поэтому рекомендуется использовать их
Неправильно использовать операторы импорта wilcard, они делают код менее читабельным, просто не делайте этого. Единственным исключением из этого правила является, например, статический импорт. import static org.junit.Assert.*;
, Нет, я не хочу импортировать каждый assertXXX
индивидуально, и я не считаю, что это вредит читабельности кода.
Если вы перечислите их по отдельности, то при чтении кода с помощью простого редактора (а не из среды разработки) будет легче определить, из каких объектов создаются пакеты. При чтении кода из сложных проектов это может сэкономить значительное время. Например, ранее, сегодня, когда я изучал код из большого проекта с открытым исходным кодом, не желая загружать все в затмение.
Опция 1, которую вы перечислили, предпочтительнее, но если есть больше классов, которые вы импортируете, скажем, из java.awt.image, то предпочтительнее всего один импорт java.awt.image.* Большинство IDE позволяют вам указать точное количество чисел импорта для использования. Например, в IDEA, мы можем использовать File->Settings->Code Style->imports
Во вкладке General есть поле Class count to use import with *
и значение по умолчанию 5.
Какой бы ни была IDE вашей команды по умолчанию. Таким образом, вы можете просто сделать автоформат вашего файла перед его фиксацией.
Если вы используете ide, например, visual studio, это, как правило, решает эту проблему для вас, так что вам даже не нужно думать об этом.
Большинство известных мне IDE выбирают вариант 1 выше. Это согласуется с некоторыми инструментами анализа кода, которые я использовал в прошлом (например, checkstyle), так как они считают плохой практикой использование * обозначения.
Импорт по отдельности избавляет компилятор от необходимости просматривать каждый пакет для каждого класса и, следовательно, ускоряет его выполнение.
Здесь нет единственно правильного ответа.
Люди, которые принесли вам Eclipse, проголосовали за индивидуальный импорт, поскольку Source/Organize Imports преобразует форму * в конкретную форму.