Eclipse/Java - вредно для импорта java. (Namespace). *?

Почему при импорте типов Eclipse использует мелкозернистый подход? В С# я привык к таким вещам, как "using System.Windows.Controls" и выполняется с ним, но Eclipse предпочитает импортировать каждый виджет, который я ссылаюсь индивидуально (с помощью сочетания Ctrl + Shift + O). Есть ли вред для импорта целого пространства имен, если я знаю, что мне нужно несколько типов в нем?

Ответ 1

Единственный вред, который может вызвать импорт подстановочных пакетов, - это повышенная вероятность конфликтов пространства имен, если в нескольких пакетах есть несколько классов с одним и тем же именем.

Скажем, например, я хочу запрограммировать использование класса ArrayList Framework Java Collections Framework в приложении AWT, которое использует компонент List GUI для отображения информации. Для примера предположим, что мы имеем следующее:

// 'ArrayList' from java.util
ArrayList<String> strings = new ArrayList<String>();

// ...

// 'List' from java.awt
List listComponent = new List()

Теперь, чтобы использовать вышеизложенное, должен быть импорт для этих двух классов, минимально:

import java.awt.List;
import java.util.ArrayList;

Теперь, если бы мы использовали подстановочный знак в пакете import, у нас было бы следующее.

import java.awt.*;
import java.util.*;

Однако теперь у нас будет проблема!

Существует класс java.awt.List и java.util.List, поэтому обращение к классу List будет неоднозначным. Нужно было бы обратиться к List с полным именем класса, если мы хотим устранить двусмысленность:

import java.awt.*;
import java.util.*;

ArrayList<String> strings = new ArrayList<String>();

// ...

// 'List' from java.awt -- need to use a fully-qualified class name.
java.awt.List listComponent = new java.awt.List()

Следовательно, бывают случаи, когда использование подстановочного пакета import может привести к проблемам.

Ответ 2

Eclipse имеет отличный параметр под названием "Организовать импорт" в диалоговом окне "Окно → Настройки", который позволяет вам сказать, когда N классов используются из пакета, выполните импорт подстановочных знаков. Я использую его при N = 2 или 3 обычно.

Ответ 3

Кто-то может прочитать ваш код без IDE - в этом случае импорт без подстановочных знаков поможет ему выяснить, какие классы используются в вашем коде.

Ответ 4

Директива import - это директива компилятор, она сообщает компилятору, где искать класс, и позволяет не всегда использовать полностью квалифицированные имена классов, например. java.util.HashMap. Но сами директивы импорта не попадают в скомпилированные файлы байт-кода, компилятор компилирует полное имя в файл .class.

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

Другими словами, директива import никак не может повлиять на выполнение кода выполнения. Однако директива import влияет на время компиляции. Кроме того, я считаю, что использование import с помощью подстановочных знаков делает код менее читаемым.

Собственно, стоимость импортных заявлений вопрос месяца на javaperformancetuning.com прекрасно суммируют это в своем заключении:

  • Не существует затрат времени исполнения от использования оператора импорта
  • Процесс компиляции может занять немного больше времени с импортом Заявление
  • Процесс компиляции может занять еще больше времени с помощью подстановочного импорта Заявление
  • Для повышения удобочитаемости утверждения импорта подстановочных знаков являются плохой практикой для ничего, кроме отброшенных классов.
  • Накладные расходы на компиляцию для операторов без подстановочных импортов: но они дают читаемость преимущества, поэтому наилучшей практикой является использование их

Ответ 5

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

Я просто использую Ctrl + Space, чтобы принудительно импортировать, когда я использую еще не импортированный класс, и импорт происходит автоматически. Затем я нажимаю Ctrl + Shift + O после того, как я реорганизую класс, чтобы удалить любые импорты, которые больше не используются.

Ответ 6

До тех пор, пока JDK 1.2 не будет компилировать этот код:

import java.awt.*;
import java.util.*;

public class Foo
{
    // List is java.awt.List
    private List list;
}

в JDK 1.2 java.util.List добавлен, и код больше не компилируется, потому что компилятор не знал, какой список был нужен (awt или util). Вы можете исправить это, добавив "import java.awt.List"; в конце импорта, но дело в том, что вам нужно что-то сделать, чтобы исправить это.

Я лично использую единственный импорт вместо импорта по требованию по двум причинам:

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

Ответ 7

С точки зрения пуриста, каждый импорт создает зависимость и потенциальный конфликт. Импорт рассматривается как необходимое зло, поэтому они сводятся к минимуму. Импорт другого пакета с * - это как запись пустой проверки. Импорт двух таких пакетов - это предоставление кому-то доступа к перемещению денег между вашими учетными записями.

С практической точки зрения это часто имеет смысл, потому что разные проекты и библиотеки используют удивительно похожие имена для разных концепций. Или, представьте, вы импортируете все из пакета A, а затем все из пакета B и используете некоторый класс C из пакета B. Если кто-то позже добавляет класс с именем C в пакет A, ваш код может сломаться!

Сказав это, я признаю, что я ленив. Я часто предварительно импортирую все в пакет, а затем пусть Eclipse организует его для меня на основе того, что я на самом деле использую.

Ответ 8

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

Это не проблема, если вы используете совместимую среду IDE, такую ​​как IntelliJ. Я бы предположил, что Eclipse и NetBeans могут управлять импортом. Он добавит вам код и скроет их из вида, чтобы они не загромождали окно. Что может быть проще?

Ответ 9

Не повреждает код. Как общий принцип, зачем импортировать что-то, если вы не собираетесь использовать?

Ответ 10

Если вы напишете какой-нибудь java-код, например

LinkedList<foo> llist = new LinkedList<foo>()  

и вы не импортировали LinkedList в свой проект, Eclipse спросит, хотите ли вы его импортировать. Поскольку вы используете LinkedList и ничего больше, он будет импортировать LinkedList. Если вы делаете что-то еще в одном проекте, например,  ArrayList<foo> alist = new ArrayList<foo>()

Затем Eclipse также скажет, что вам нужно импортировать ArrayList, но ничего больше. Eclipse использует только то, что вам нужно, на основе любых вызовов библиотеки. Если вам нужно несколько типов или элементов из одной и той же библиотеки, нет вреда при использовании

import java.namespace.*

чтобы идти вперед и вводить другие предметы, которые вам нужны. Eclipse не волнует, пока вы импортируете пакеты и библиотеки, содержащие элементы, на которые вы ссылаетесь, такие как Scanners, LinkedLists и т.д.

С точки зрения читаемости это другой вопрос. Если вы хотите, чтобы люди явно знали, что именно вы импортируете, то вызов каждого виджета или пакета может быть в порядке. Это может стать довольно утомительным, если вы используете множество различных функций из одного пакета в стандартной библиотеке и можете сделать ваши заголовки файлов довольно длинными, следовательно. * Wildcard. Там нет вреда при импорте с помощью подстановочных знаков, это действительно сводится к вашим стандартам кодирования и насколько прозрачным вы хотите, чтобы ваши заголовки классов были.

Ответ 11

Импортирование каждого класса явно дает жесткую привязку между коротким именем (например, прокси) и длинным именем (например, java.lang.reflect.Proxy), а не свободным связыванием, говорящим, что в java.lang.reflect.* java.io.* или java.net.* или в другом месте импортируемых вами подстановочных импортов.

Это может быть проблемой, если по какой-либо причине другой класс с именем Proxy появляется где-то в java.io.* или java.net.* или ваш собственный код, поскольку компилятор тогда не знает, какой класс Proxy вы хотите, как если бы он был, если бы вы явно импортировали java.lang.reflect.Proxy.

Приведенный выше пример не подтвержден. Класс java.net.Proxy был представлен на Java 5 и нарушил бы ваш код, если бы он был написан как намеченный выше. См. Официальное объяснение Sun о том, как обойти проблемы подстановочных знаков на http://java.sun.com/j2se/1.5.0/compatibility.html

(Импорт подстановочных знаков - это просто удобный механизм для тех, кто не использует IDE для поддержки операторов импорта. Если вы используете среду IDE, то пусть это поможет вам:)