답변:
이것의 유일한 문제는 로컬 네임 스페이스를 혼란스럽게한다는 것입니다. 예를 들어, Swing 앱을 작성 중이므로 need java.awt.Event
이 있고 회사의 캘린더 시스템과 인터페이스하고 있다고 가정 해 보겠습니다 com.mycompany.calendar.Event
. 와일드 카드 방법을 사용하여 둘 다 가져 오는 경우 다음 세 가지 중 하나가 발생합니다.
java.awt.Event
와 사이에 명백한 이름 충돌이 com.mycompany.calendar.Event
있으므로 컴파일조차 할 수 없습니다..*
하지만 ( 두 가지 가져 오기 중 하나만 수행함 ) 잘못된 것이므로 코드에서 유형이 잘못되었다고 주장하는 이유를 알아내는 데 어려움을 겪습니다.com.mycompany.calendar.Event
가 없지만 나중에 코드를 추가하면 이전에 유효한 코드가 갑자기 컴파일을 중지합니다.모든 수입을 명시 적으로 나열하는 이점은 사용하려는 클래스를 한 눈에 알 수 있으므로 코드를 훨씬 쉽게 읽을 수 있다는 것입니다. 빠른 일회성 작업을 수행하는 경우 명시 적으로 잘못된 것은 없지만 미래의 관리자는 명확성을 고맙게 생각합니다.
다음 은 스타 수입에 대한 투표 입니다 . import 문은 클래스가 아닌 패키지 를 가져 오기위한 것 입니다. 전체 패키지를 가져 오는 것이 훨씬 깔끔합니다. 여기에서 식별 된 문제 (예 : java.sql.Date
vs java.util.Date
)는 다른 방법으로 쉽게 해결할 수 있으며 특정 수입품으로는 실제로 해결되지 않으며 모든 클래스에서 미친 수입품을 정당화하지는 않습니다. 소스 파일을 열고 100 개의 import 문을 페이징해야하는 것보다 더 당혹스러운 일은 없습니다.
특정 가져 오기를 수행하면 리팩토링이 더 어려워집니다. 클래스를 제거하거나 이름을 바꾸면 특정 가져 오기를 모두 제거해야합니다 . 동일한 패키지에서 구현을 다른 클래스로 전환하면 가져 오기를 수정해야합니다. 이러한 추가 단계를 자동화 할 수는 있지만 실질적인 이익을 얻지 못하면 생산성에 영향을 미칩니다.
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에 List가 있으며 충돌이 없습니다.
이제 완벽하게 작동하는 코드를 체크인하고 1 년 후 다른 사람이 코드를 가져와 편집하고 Java 1.2를 사용한다고 가정합니다.
Java 1.2는 List라는 인터페이스를 java.util에 추가했습니다. 팔! 충돌. 완벽하게 작동하는 코드는 더 이상 작동하지 않습니다.
이것은 EVIL 언어 기능입니다. 패키지에 유형이 추가 되어 코드 컴파일이 중단 될 이유 는 없습니다 .
또한 독자가 사용중인 "Foo"를 결정하기가 어렵습니다.
java.util.List
vs java.awt.List
는 알아 내기에는 나쁘지 않지만 클래스 이름이 Configuration
있고 여러 종속성 라이브러리가 최신 maven repo 버전에 추가 했을 때 시도하십시오 .
그건 하지 자바 import 문에 와일드 카드를 사용하는 것이 나쁜.
에서 클린 코드 로버트 C. 마틴은 실제로 긴 수입 목록을 피하기 위해 그들을 사용하는 것이 좋습니다.
권장 사항은 다음과 같습니다.
J1 : 와일드 카드를 사용하여 긴 가져 오기 목록 피하기
패키지에서 두 개 이상의 클래스를 사용하는 경우
수입품 포장. *;
수입품의 긴 목록은 독자에게 어려워합니다. 우리는 80 개의 수입 라인으로 모듈의 상단을 어수선하게 만들고 싶지 않습니다. 오히려 우리는 수입품이 우리가 어떤 패키지와 협력하는지에 대한 간결한 진술이되기를 원합니다.
와일드 카드 가져 오기는 그렇지 않지만 특정 가져 오기는 어려운 종속성입니다. 클래스를 구체적으로 가져 오는 경우 해당 클래스가 존재해야합니다. 그러나 와일드 카드가 포함 된 패키지를 가져 오는 경우 특정 클래스가 필요하지 않습니다. import 문은 단순히 이름을 찾을 때 검색 경로에 패키지를 추가합니다. 따라서 이러한 가져 오기로 인해 진정한 종속성이 생성되지 않으므로 모듈을 덜 결합시키는 역할을합니다.
특정 가져 오기의 긴 목록이 유용한 경우가 있습니다. 예를 들어 레거시 코드를 처리하고 모의 및 스텁을 빌드하는 데 필요한 클래스를 찾으려면 특정 가져 오기 목록을 내려 모든 클래스의 정규화 된 이름을 찾은 다음 적절한 그루터기. 그러나 특정 수입품에 대한 이러한 사용은 매우 드 rare니다. 또한 대부분의 최신 IDE에서는 단일 명령으로 와일드 카드 가져 오기를 특정 가져 오기 목록으로 변환 할 수 있습니다. 따라서 레거시의 경우에도 와일드 카드를 가져 오는 것이 좋습니다.
와일드 카드 가져 오기로 인해 이름 충돌 및 모호성이 발생할 수 있습니다. 이름은 같지만 패키지가 다른 두 개의 클래스를 특별히 가져 오거나 최소한 사용할 때는 정규화해야합니다. 이것은 성가신 일이 될 수 있지만 와일드 카드 가져 오기를 사용하는 것이 여전히 일반적인 가져 오기보다 낫습니다.
성능 : 바이트 코드가 동일하므로 성능에 영향을 미치지 않습니다. 컴파일 오버 헤드가 발생할 수 있습니다.
컴파일 : 내 개인 컴퓨터에서 가져 오기없이 빈 클래스를 컴파일하는 데 100ms가 걸리지 만 java. *는 170ms가 걸립니다.
import java.*
아무것도 가져 오지 않습니다. 왜 차이가 있을까요?
많은 양의 Java를 사용하여 작업 한 대부분의 장소는 명시 적 수입을 코딩 표준의 일부로 만듭니다. 빠른 프로토 타이핑에 여전히 *를 사용한 다음 코드를 제품화 할 때 가져 오기 목록을 확장합니다 (일부 IDE에서도이를 수행함).
이전 프로젝트에서 * -imports에서 특정 imports로 변경하면 컴파일 시간이 약 10 분에서 5 분으로 절반으로 단축되었습니다. * -import는 컴파일러가 사용자가 사용한 것과 일치하는 클래스에 대해 나열된 각 패키지를 검색하도록합니다. 이 시간은 작을 수 있지만 큰 프로젝트에는 더해집니다.
* -import의 부작용은 개발자가 필요한 것을 생각하기보다는 일반적인 import line을 복사하여 붙여 넣는 것입니다.
컴파일러가 *를 구체적인 클래스 이름으로 자동 대체하므로 런타임 영향은 없습니다. .class 파일을 디 컴파일하면을 볼 수 없습니다 import ...*
.
C # 은 패키지 이름 만 사용할 수 있으므로 항상 * (암시 적으로)를 사용합니다 using
. 클래스 이름을 전혀 지정할 수 없습니다. Java는 C # 다음에이 기능을 소개합니다. (자바는 여러 측면에서 매우 까다 롭지 만이 주제를 넘어선 것입니다).
Intellij Idea에서 "가져 오기 구성"을 수행하면 동일한 패키지의 여러 가져 오기가 *로 자동 대체됩니다. 이 기능은 끌 수 없으므로 필수 기능입니다 (임계 값을 늘릴 수 있음).
수락 된 답변으로 표시된 사례가 유효하지 않습니다. *가 없으면 여전히 같은 문제가 있습니다. * 사용 여부에 관계없이 코드에 pakcage 이름을 지정해야합니다.
가장 중요한 것은 가져 오기 java.awt.*
를 통해 프로그램이 향후 Java 버전과 호환되지 않을 수 있다는 것입니다.
"ABC"라는 클래스가 있다고 가정하고 JDK 8을 사용하고 있으며 import를 가져옵니다 java.util.*
. 이제 Java 9이 나오고 java.util
우연히 "ABC"라고 불리는 새로운 클래스의 패키지 가 있다고 가정하십시오 . 컴파일러는 "ABC"라는 이름으로 자신의 클래스 또는 새 클래스를 의미하는지 알 수 없기 때문에 이제 Java 9에서 컴파일되지 않습니다.java.awt
.
java.awt
실제로 사용 하는 클래스 만 명시 적으로 가져 오면 문제가 발생하지 않습니다 .
자원:
Stream
Java 8의 java.util에서 Java에 추가 된 새 클래스의 예로 사용할 수 있습니다 .
양쪽에서 유효한 모든 요점 중에서 와일드 카드를 피해야하는 주된 이유를 찾지 못했습니다. 코드를 읽고 모든 클래스가 무엇인지 또는 해당 정의가 언어 또는 언어로 정의되어 있지 않은지 직접 알고 싶습니다. 파일이있는 위치 둘 이상의 패키지를 가져 오면 * 인식하지 못하는 클래스를 찾기 위해 모든 패키지를 검색해야합니다. 가독성은 최고이며, 코드가 를 읽을 때 IDE가 필요 합니다.