Jedynym problemem jest to, że zaśmieca on twoją lokalną przestrzeń nazw. Załóżmy na przykład, że piszesz aplikację Swing, a więc potrzebujesz java.awt.Event
, a także współpracujesz z systemem kalendarza firmy, który ma com.mycompany.calendar.Event
. Jeśli zaimportujesz oba za pomocą metody wieloznacznej, wydarzy się jedna z tych trzech rzeczy:
- Masz bezpośredni konflikt nazw między
java.awt.Event
i com.mycompany.calendar.Event
, więc nie możesz nawet skompilować.
- W rzeczywistości udaje Ci się zaimportować tylko jeden (tylko jeden z dwóch importów
.*
), ale jest to niewłaściwy i próbujesz dowiedzieć się, dlaczego kod twierdzi, że ten typ jest nieprawidłowy.
- Kiedy kompilujesz swój kod, nie ma go
com.mycompany.calendar.Event
, ale kiedy dodają go później, twój poprzednio poprawny kod nagle przestaje się kompilować.
Zaletą jawnego wyszczególnienia wszystkich importów jest to, że mogę na pierwszy rzut oka stwierdzić, której klasy chciałeś użyć, co po prostu znacznie ułatwia czytanie kodu. Jeśli robisz szybką jednorazową rzecz, nie ma nic wyraźnie złego , ale przyszli opiekunowie będą ci wdzięczni za twoją jasność.
Oto głosowanie na import gwiazd. Instrukcja importu służy do importowania pakietu , a nie klasy. Importowanie całych paczek jest znacznie czystsze; problemy zidentyfikowane tutaj (np.
java.sql.Date
vsjava.util.Date
) można łatwo rozwiązać za pomocą innych środków, tak naprawdę nie rozwiązanych konkretnym przywozem i na pewno nie uzasadniają szalenie pedantycznego importu we wszystkich klasach. Nie ma nic bardziej niepokojącego niż otwieranie pliku źródłowego i przeglądanie 100 instrukcji importu.Dokonanie określonego importu utrudnia refaktoryzację; jeśli usuniesz / zmienisz nazwę klasy, musisz usunąć wszystkie jej określone importy. Jeśli przełączysz implementację na inną klasę w tym samym pakiecie, musisz naprawić importowanie. Te dodatkowe kroki można zautomatyzować, ale w rzeczywistości są one hitami produktywności bez żadnego rzeczywistego zysku.
Nawet gdyby Eclipse nie domyślnie importował klasy, wszyscy nadal importowaliby gwiazdki. Przykro mi, ale tak naprawdę nie ma racjonalnego uzasadnienia dla wykonywania określonych importów.
Oto jak radzić sobie z konfliktami klasowymi:
źródło
Foo
, a jeśli czytam twój kod bez użycia IDE (ponieważ twoim argumentem jest to, że nie powinienem go używać), skąd będę wiedział, z którego pakietuFoo
pochodzi ? Jasne, używając IDE, IDE powie mi, ale cały twój argument jest taki, że powinienem być w stanie odczytać kod bez niego. Wykonywanie jawnych importów pomaga udokumentować kod (świetny powód, aby unikać symboli wieloznacznych) , i jest o wiele bardziej prawdopodobne, że będę czytać kod bez użycia IDE, niż że będę pisać kod bez używania IDE.zobacz mój artykuł Import na żądanie jest zły
Krótko mówiąc, największym problemem jest to, że kod może się zepsuć, gdy klasa zostanie dodana do importowanego pakietu. Na przykład:
W Javie 1.1 było to w porządku; Lista została znaleziona w java.awt i nie było konfliktu.
Załóżmy teraz, że wpiszesz doskonale działający kod, a rok później ktoś inny wyda go, aby go edytować i używa Java 1.2.
Java 1.2 dodał interfejs o nazwie List do java.util. BUM! Konflikt. Doskonale działający kod już nie działa.
To jest funkcja języka ZŁEGO . Jest NO powodem, że kod powinien zatrzymać kompilacji tylko dlatego, że typ jest dodany do pakietu ...
Ponadto utrudnia czytelnikowi określenie, którego „Foo” używasz.
źródło
java.util.List
vsjava.awt.List
nie jest takie złe, żeby to rozgryźć, ale wypróbuj je, gdy nazwa klasy jest,Configuration
a wiele bibliotek zależności dodało ją w swojej najnowszej wersji repozytorium maven.To nie złe użycie dziką kartę z oświadczeniem importowej Java.
W Clean Code Robert C. Martin zaleca używanie ich, aby uniknąć długich list importów.
Oto zalecenie:
źródło
Wydajność : brak wpływu na wydajność, ponieważ kod bajtu jest taki sam. chociaż doprowadzi to do pewnych kosztów kompilacji.
Kompilacja : na mojej osobistej maszynie kompilowanie pustej klasy bez importowania niczego zajmuje 100 ms, ale ta sama klasa podczas importowania Java. * Zajmuje 170 ms.
źródło
import java.*
nic nie importuje. Dlaczego miałoby to mieć znaczenie?Zaśmieca twoją przestrzeń nazw, wymagając od ciebie pełnego określenia wszelkich niejednoznacznych nazw klas. Najczęstszym tego zjawiskiem jest:
Pomaga także uszczegółowić twoje zależności, ponieważ wszystkie twoje zależności są wymienione w górnej części pliku.
źródło
Większość miejsc, w których pracowałem i które używają znacznej ilości Java, czynią jawne importowanie częścią standardu kodowania. Czasami wciąż używam * do szybkiego prototypowania, a następnie rozwijam listy importu (niektóre IDE też to zrobią dla Ciebie) podczas tworzenia kodu.
źródło
Preferuję określone importowanie, ponieważ pozwala mi zobaczyć wszystkie odnośniki zewnętrzne użyte w pliku bez patrzenia na cały plik. (Tak, wiem, że niekoniecznie będzie zawierać w pełni kwalifikowane referencje. Ale unikam ich, gdy tylko jest to możliwe).
źródło
W poprzednim projekcie odkryłem, że zmiana z * -importów na określone importy skróciła czas kompilacji o połowę (z około 10 minut do około 5 minut). * -Import powoduje, że kompilator przeszukuje każdy z wymienionych pakietów w poszukiwaniu klasy pasującej do użytej. Ten czas może być niewielki, ale w przypadku dużych projektów stanowi dużą sumę.
Efektem ubocznym importu * było to, że programiści kopiowali i wklejali wspólne linie importu, zamiast myśleć o tym, czego potrzebowali.
źródło
W książce DDD
A jeśli zaśmieca lokalną przestrzeń nazw, to nie twoja wina - obwiniaj rozmiar paczki.
źródło
Nie ma wpływu na środowisko uruchomieniowe, ponieważ kompilator automatycznie zastępuje * konkretnymi nazwami klas. Jeśli zdekompilujesz plik .class, nigdy nie zobaczysz
import ...*
.C # zawsze używa * (niejawnie), ponieważ można tylko
using
spakować nazwę. Nigdy nie można w ogóle podać nazwy klasy. Java wprowadza tę funkcję po c #. (Java jest bardzo trudna pod wieloma względami, ale wykracza poza ten temat).W programie Intellij Idea podczas „organizowania importów” automatycznie zastępuje wiele importów tego samego pakietu znakiem *. Jest to funkcja obowiązkowa, ponieważ nie można jej wyłączyć (chociaż można zwiększyć próg).
Przypadek wymieniony w zaakceptowanej odpowiedzi jest nieprawidłowy. Bez * nadal masz ten sam problem. Musisz podać nazwę pakietu w swoim kodzie, bez względu na to, czy używasz * czy nie.
źródło
Dla przypomnienia: po dodaniu importu wskazujesz również swoje zależności.
Szybko można zobaczyć, jakie są zależności plików (z wyjątkiem klas o tej samej przestrzeni nazw).
źródło
Najważniejsze jest to, że importowanie
java.awt.*
może spowodować, że Twój program będzie niezgodny z przyszłą wersją Java:Załóżmy, że masz klasę o nazwie „ABC”, używasz JDK 8 i importujesz
java.util.*
. Teraz załóżmy, że Java 9 wychodzi i ma nową klasę w pakiecie,java.util
która przypadkiem jest również nazywana „ABC”. Twój program nie będzie się teraz kompilował na Javie 9, ponieważ kompilator nie wie, czy pod nazwą „ABC” masz na myśli własną klasę lub nową klasę wjava.awt
.Nie będziesz mieć tego problemu, gdy zaimportujesz tylko te klasy, z
java.awt
których faktycznie korzystasz.Zasoby:
Importowanie Java
źródło
Stream
jako przykład nowej klasy dodanej w Javie w java.util w Javie 8 ...Spośród wszystkich ważnych argumentów przedstawionych po obu stronach nie znalazłem mojego głównego powodu, aby unikać znaku wieloznacznego: Lubię czytać kod i wiedzieć bezpośrednio, co to jest każda klasa, lub jeśli jej definicja nie jest w języku lub plik, gdzie go znaleźć. W przypadku importowania więcej niż jednego pakietu za pomocą * muszę przeszukać każdy z nich, aby znaleźć klasę, której nie rozpoznaję. Czytelność jest najwyższa i zgadzam się, że kod nie powinien wymagać IDE do odczytu.
źródło