Відповіді:
Єдина проблема з цим полягає в тому, що він захаращує ваш локальний простір імен. Наприклад, скажімо, що ви пишете додаток Swing, і так вам потрібно java.awt.Event
, а також взаємодієте з системою календарів компанії, яка є com.mycompany.calendar.Event
. Якщо ви імпортуєте обидва, використовуючи метод підстановки, відбувається одна з цих трьох речей:
java.awt.Event
і com.mycompany.calendar.Event
, і тому ви навіть не можете його скласти..*
), але це неправильний, і ви намагаєтесь з’ясувати, чому ваш код стверджує, що тип неправильний.com.mycompany.calendar.Event
, але коли вони згодом додають один, ваш попередньо дійсний код раптом припиняється компілювати.Перевага чітко перерахувати весь імпорт полягає в тому, що я можу з першого погляду сказати, який клас ви мали намір використати, що просто робить читання коду набагато простішим. Якщо ви просто робите швидку разову річ, явно нічого поганого немає , але майбутні технічні працівники будуть вдячні вам за вашу чіткість.
Ось голосування за імпорт зірок. Заява про імпорт призначена для імпорту пакету , а не класу. Набагато чистіше імпортувати цілі пакети; виявлені проблеми тут (наприклад , java.sql.Date
проти java.util.Date
) легко виправити з допомогою інших засобів, а НЕ на насправді вирішувати за рахунок імпорту конкретних і , безумовно , не виправдовують душевнохворого педантичних імпорту по всіх класах. Немає нічого більш неприємного, ніж відкрити вихідний файл і перегортати 100 заяв про імпорт.
Здійснення конкретного імпорту ускладнює рефакторинг; якщо ви видалите / перейменуєте клас, вам потрібно видалити весь його конкретний імпорт. Якщо ви переключите реалізацію на інший клас в одному пакеті, вам доведеться виправити імпорт. Хоча ці додаткові кроки можна автоматизувати, вони справді досягають продуктивності без реального виграшу.
Навіть якби Eclipse не робив імпорт класів за замовчуванням, все одно б імпортували зірки. Вибачте, але дійсно немає раціонального обґрунтування здійснення конкретного імпорту.
Ось як поводитися з класовими конфліктами:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Foo
, і якщо я читаю ваш код без використання IDE (оскільки ваш аргумент полягає в тому, що я не повинен використовувати його), як я дізнаюся, з якого пакета Foo
прийшов ? Звичайно, використовуючи IDE, IDE скаже мені, але весь ваш аргумент полягає в тому, що я повинен мати можливість читати код без одного. Явний імпорт допомагає документувати код (велика причина уникнути підстановки) , і набагато більше шансів, що я буду читати код без використання IDE, ніж те, що я буду писати код, не використовуючи IDE.
дивіться мою статтю Імпорт на вимогу - це зло
Коротше кажучи, найбільша проблема полягає в тому, що ваш код може зламатися, коли клас додається до пакету, який ви імпортуєте. Наприклад:
import java.awt.*;
import java.util.*;
// ...
List list;
У Java 1.1 це було чудово; Список знайдений у java.awt, і конфлікту не було.
Тепер припустимо, ви перевірили свій ідеально працюючий код, а через рік хтось інший виведе його для редагування і використовує Java 1.2.
Java 1.2 додала в java.util інтерфейс з назвою List. БУМ! Конфлікт. Ідеально працюючий код більше не працює.
Це особливість мови EVIL . Там немає НІЯКОЇ причини того, що код повинен припинити збір тільки тому тип додається в пакет ...
Крім того, читачеві важко визначити, який саме "Foo" ви використовуєте.
java.util.List
vs java.awt.List
не надто погано, щоб розібратися, але спробуйте, коли ім'я класу є, Configuration
і кілька бібліотек залежностей додали його в останню версію Maven Repo.
Це НЕ погано , щоб використовувати джокер з оператором імпорту Java.
У чистому коді Роберт К. Мартін фактично рекомендує використовувати їх, щоб уникнути довгих списків імпорту.
Ось рекомендація:
J1: уникайте довгих імпортних списків, використовуючи символи
Якщо ви використовуєте два або більше класів з пакету, то імпортуйте весь пакет за допомогою
імпортний пакет. *;
Довгі переліки імпорту неприємні для читача. Ми не хочемо захаращувати вершини наших модулів 80 лініями імпорту. Швидше ми хочемо, щоб імпорт був стислим твердженням про те, з якими пакетами ми співпрацюємо.
Конкретний імпорт є важкою залежністю, тоді як імпорт wildcard - ні. Якщо ви спеціально імпортуєте клас, він повинен існувати. Але якщо ви імпортуєте пакет із символом підстановки, особливих класів не потрібно існувати. Заява про імпорт просто додає пакунок до шляху пошуку під час пошуку імен. Таким чином, жодна справжня залежність від такого імпорту не створюється, і тому вони служать для того, щоб наші модулі були менш зв'язаними.
Бувають випадки, коли довгий перелік конкретного імпорту може бути корисним. Наприклад, якщо ви маєте справу зі застарілим кодом і хочете дізнатися, для яких класів потрібно створити макети та заглушки, ви можете перейти до списку конкретного імпорту, щоб дізнатися справжні кваліфіковані імена всіх цих класів, а потім поставити відповідні заглушки на місці. Однак таке використання для конкретного імпорту трапляється дуже рідко. Крім того, більшість сучасних IDE дозволять вам перетворити імпорт під маркою в список конкретного імпорту за допомогою однієї команди. Тож навіть у застарілому випадку краще імпортувати маклери.
Імпорт шаблонів іноді може викликати конфлікти і неоднозначності імен. Два класи з однаковою назвою, але в різних упаковках, потрібно буде спеціально імпортувати або хоча б спеціально кваліфікувати при їх використанні. Це може спричинити занепокоєння, але досить рідко, що використання імпортних символів все ще краще, ніж конкретний імпорт.
Продуктивність : Не впливає на продуктивність, оскільки байтовий код не однаковий. хоча це призведе до деяких накладних витрат.
Компіляція : на моїй персональній машині компіляція порожнього класу без імпорту нічого займає 100 мс, але той самий клас при імпорті Java. * Займає 170 мс.
import java.*
імпортувати нічого. Чому це має значення?
Це захаращує ваше простір імен, вимагаючи від вас повністю вказати будь-які імена класів, які є неоднозначними. Найбільш часто це відбувається з:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
Це також допомагає зробити ваші залежності конкретними, оскільки всі ваші залежності перераховані у верхній частині файлу.
Більшість місць, де я працював, які використовують будь-яку значну кількість Java, явно імпортують частину стандарту кодування. Я інколи все ще використовую * для швидкого прототипування, а потім розширюю списки імпорту (деякі IDE будуть робити це і для вас), коли виробляють код.
У попередньому проекті я виявив, що перехід від * -імпорту до конкретного імпорту скоротив час складання вдвічі (приблизно з 10 хвилин до приблизно 5 хвилин). * -Import змушує компілятор шукати кожен із перелічених пакетів класу, який відповідає тому, який ви використовували. Хоча цей час може бути невеликим, він додається для великих проектів.
Побічним ефектом * -імпорту було те, що розробники копіювали та вставляли загальні лінії імпорту, а не думали про те, що їм потрібно.
В якій би технології розробки не базувалася реалізація, шукайте способи мінімізації роботи МОДУЛІВ, що рефакторингу. У Java немає імпорту від імпорту в окремі класи, але ви можете принаймні імпортувати цілі пакети за один раз, що відображає намір, що пакети є сильно згуртованими одиницями, одночасно зменшуючи зусилля щодо зміни назв пакетів.
І якщо він захаращує місцевий простір імен, це не ваша вина - звинувачуйте розмір пакету.
Немає впливу на час виконання, оскільки компілятор автоматично замінює * конкретними іменами класів. Якщо ви декомпілюєте файл .class, ви ніколи не побачите import ...*
.
C # завжди використовує * (неявно), оскільки ви можете тільки using
назву пакета. Ніколи не можна вказувати назву класу. Java вводить функцію після c #. (Ява настільки хитра в багатьох аспектах, але це поза цією темою).
У Intellij Idea, коли ви "організовуєте імпорт", він автоматично замінює багаторазовий імпорт одного пакету на *. Це обов'язкова функція, оскільки ви не можете її вимкнути (хоча ви можете збільшити поріг).
Справа, перелічена прийнятою відповіддю, недійсна. Без * у вас все-таки вийшов той самий випуск. Вам потрібно вказати ім'я пакунка у коді, незалежно від того, використовуєте ви * чи ні.
Для запису: Коли ви додаєте імпорт, ви також вказуєте свої залежності.
Ви швидко зможете побачити, які існують файли (за винятком класів одного простору імен).
Найважливішим є те, що імпорт java.awt.*
може зробити вашу програму несумісною з майбутньою версією Java:
Припустимо, у вас клас з назвою "ABC", ви використовуєте JDK 8 і імпортуєте java.util.*
. Тепер припустимо, що виходить Java 9, і в неї є новий клас в пакеті, java.util
який за збігом обставин також може називатися "ABC". Тепер ваша програма не буде компілюватись на Java 9, оскільки компілятор не знає, чи під ім'ям "ABC" ви маєте на увазі власний клас чи новий клас у java.awt
.
У вас не буде такої проблеми, коли ви імпортуєте лише ті класи, які явно java.awt
використовуєте.
Ресурси:
Stream
як приклад нового класу, доданого на Java в java.util на Java 8 ...
Серед усіх дійсних моментів, зроблених з обох сторін, я не знайшов своєї основної причини уникати підстановки: мені подобається читати код і безпосередньо знати, що таке кожен клас, або якщо його визначення не в мові чи файл, де його знайти. Якщо з імпортовано більше одного пакету * Я повинен шукати кожен з них, щоб знайти клас, який я не впізнаю. Читання є вищим, і я погоджуюся, що код не повинен вимагати IDE для його читання.