development

Java 가져 오기 명령문에 와일드 카드를 사용하는 이유가 무엇입니까?

big-blog 2020. 2. 26. 07:57
반응형

Java 가져 오기 명령문에 와일드 카드를 사용하는 이유가 무엇입니까?


다음과 같은 단일 명령문을 사용하는 것이 훨씬 편리하고 깨끗합니다.

import java.awt.*;

개별 클래스를 가져 오는 것보다

import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...

import명령문 에서 와일드 카드를 사용하는 데 어떤 문제가 있습니까?


이것의 유일한 문제는 로컬 네임 스페이스를 혼란스럽게한다는 것입니다. 예를 들어, Swing 앱을 작성 중이므로 need java.awt.Event가 있고을 (를) 가진 회사의 캘린더 시스템과 인터페이스하고 있다고 가정 com.mycompany.calendar.Event합니다. 와일드 카드 방법을 사용하여 둘 다 가져 오는 경우 다음 세 가지 중 하나가 발생합니다.

  1. java.awt.Event사이에 명백한 이름 충돌이 com.mycompany.calendar.Event있으므로 컴파일조차 할 수 없습니다.
  2. 실제로 하나만 가져 오도록 관리 .*하지만 ( 두 가지 가져 오기 중 하나만 수행함 ) 잘못된 것이므로 코드에서 유형이 잘못되었다고 주장하는 이유를 알아내는 데 어려움을 겪습니다.
  3. 코드를 컴파일 할 때 no com.mycompany.calendar.Event가 없지만 나중에 코드를 추가하면 이전에 유효한 코드가 갑자기 컴파일을 중지합니다.

모든 수입을 명시 적으로 나열하는 이점은 사용하려는 클래스를 한 눈에 알 수 있으므로 코드를 훨씬 쉽게 읽을 수 있다는 것입니다. 빠른 일회성 작업을 수행하는 경우 명시 적으로 잘못된 것은 없지만 미래의 관리자는 명확성을 고맙게 생각합니다.


다음 스타 수입에 대한 투표 입니다 . import 문은 클래스가 아닌 패키지 를 가져 오기위한 것 입니다. 전체 패키지를 가져 오는 것이 훨씬 깔끔합니다. 여기에서 식별 된 문제 (예 : java.sql.Datevs java.util.Date)는 다른 방법으로 쉽게 해결할 수 있으며 특정 수입품으로는 실제로 해결되지 않으며 모든 클래스에서 미친 수입품을 정당화하지는 않습니다. 소스 파일을 열고 100 개의 import 문을 페이징해야하는 것보다 더 당혹스러운 일은 없습니다.

특정 가져 오기를 수행하면 리팩토링이 더 어려워집니다. 클래스를 제거하거나 이름을 바꾸면 특정 가져 오기를 모두 제거해야합니다 . 동일한 패키지에서 구현을 다른 클래스로 전환하면 가져 오기를 수정해야합니다. 이러한 추가 단계를 자동화 할 수는 있지만 실질적인 이익을 얻지 못하면 생산성이 크게 떨어집니다.

Eclipse가 기본적으로 클래스 가져 오기를 수행하지 않더라도 모든 사용자는 여전히 스타 가져 오기를 수행합니다. 죄송합니다. 특정 수입품에 대한 합리적인 근거는 없습니다.

클래스 충돌을 처리하는 방법은 다음과 같습니다.

import java.sql.*;
import java.util.*;
import java.sql.Date;

내 기사를 참조하십시오 주문형 가져 오기는 악입니다

요컨대, 가장 큰 문제는 클래스 를 가져올 패키지에 추가 할 때 코드가 손상 될 수 있다는 것 입니다. 예를 들면 다음과 같습니다.

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"를 결정하기가 어렵습니다.


그건 하지 자바 import 문에 와일드 카드를 사용하는 것이 나쁜.

에서 클린 코드 로버트 C. 마틴은 실제로 긴 수입 목록을 피하기 위해 그들을 사용하는 것이 좋습니다.

권장 사항은 다음과 같습니다.

J1 : 와일드 카드를 사용하여 긴 가져 오기 목록 피하기

패키지에서 두 개 이상의 클래스를 사용하는 경우 전체 패키지를

수입품 포장. *;

수입품의 긴 목록은 독자에게 어려워합니다. 우리는 80 개의 수입 라인으로 모듈의 상단을 어수선하게 만들고 싶지 않습니다. 우리는 수입품이 우리가 어떤 패키지와 협력하는지에 대한 간결한 진술이되기를 원합니다.

와일드 카드 가져 오기는 그렇지 않지만 특정 가져 오기는 어려운 종속성입니다. 클래스를 구체적으로 가져 오는 경우 해당 클래스가 존재해야합니다. 그러나 와일드 카드가 포함 된 패키지를 가져 오는 경우 특정 클래스가 필요하지 않습니다. import 문은 단순히 이름을 찾을 때 검색 경로에 패키지를 추가합니다. 따라서 이러한 가져 오기로 인해 진정한 종속성이 생성되지 않으므로 모듈을 덜 결합시키는 역할을합니다.

특정 가져 오기의 긴 목록이 유용 할 수있는 경우가 있습니다. 예를 들어 레거시 코드를 처리하고 모의 및 스텁을 빌드하는 데 필요한 클래스를 찾으려면 특정 가져 오기 목록을 내려 모든 클래스의 정규화 된 이름을 찾은 다음 적절한 스텁이 있습니다. 그러나 특정 수입품에 대한 이러한 사용은 매우 드 rare니다. 또한 대부분의 최신 IDE에서는 단일 명령으로 와일드 카드 가져 오기를 특정 가져 오기 목록으로 변환 할 수 있습니다. 따라서 기존의 경우에도 와일드 카드를 가져 오는 것이 좋습니다.

와일드 카드 가져 오기는 때때로 이름 충돌 및 모호성을 유발할 수 있습니다. 이름은 같지만 패키지가 다른 두 개의 클래스를 특별히 가져 오거나 최소한 사용할 때는 정규화해야합니다. 이것은 성가신 일이 될 수 있지만 와일드 카드 가져 오기를 사용하는 것이 여전히 특정 가져 오기보다 낫습니다.


네임 스페이스가 복잡해져 모호한 클래스 이름을 완전히 지정해야합니다. 이것의 가장 흔한 발생은 다음과 같습니다.

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

...
List blah; // Ambiguous, needs to be qualified.

또한 모든 종속성이 파일 맨 위에 나열되므로 종속성을 구체적으로 만드는 데 도움이됩니다.


성능 : 바이트 코드가 동일하므로 성능에 영향을 미치지 않습니다. 컴파일 오버 헤드가 발생할 수 있습니다.

컴파일 : 내 개인 컴퓨터에서 아무것도 가져 오지 않고 빈 클래스를 컴파일하는 데 100ms가 걸리지 만 java. *는 170ms가 걸립니다.


  1. 클래스 이름 충돌을 식별하는 데 도움이됩니다. 이름이 같은 다른 패키지의 두 클래스. 이것은 * import로 마스킹 될 수 있습니다.
  2. 의존성을 명시 적으로 만들어서 나중에 코드를 읽어야하는 사람은 가져 오려는 의미와 가져 오지 않은 의미를 알 수 있습니다.
  3. 컴파일러가 전체 패키지를 검색하여 depdencies를 식별 할 필요가 없기 때문에 컴파일 속도를 높일 수 있습니다.
  4. 최신 IDE에서는 명시 적 가져 오기의 불편한 측면이 최소화됩니다. 대부분의 IDE를 사용하면 가져 오기 섹션을 축소 할 수 있으므로 필요한 경우 가져 오기를 자동으로 채우고 사용하지 않는 가져 오기를 자동으로 식별하여 정리할 수 있습니다.

많은 양의 Java를 사용하여 작업 한 대부분의 장소는 명시 적으로 가져 오기를 코딩 표준의 일부로 만듭니다. 빠른 프로토 타이핑에 여전히 *를 사용한 다음 코드를 제품화 할 때 가져 오기 목록을 확장합니다 (일부 IDE에서도이를 수행함).


전체 파일을 보지 않고 파일에 사용 된 모든 외부 참조를 볼 수 있기 때문에 특정 가져 오기를 선호합니다. (예, 반드시 정규화 된 참조가 반드시 표시되는 것은 아니라는 것을 알고 있습니다. 그러나 가능하면 항상 참조를 피하십시오.)


이전 프로젝트에서 * -imports에서 특정 imports로 변경하면 컴파일 시간이 절반으로 줄었습니다 (약 10 분에서 약 5 분). * -import는 컴파일러가 사용자가 사용한 것과 일치하는 클래스에 대해 나열된 각 패키지를 검색하도록합니다. 이 시간은 작을 수 있지만 큰 프로젝트에는 더해집니다.

* -import의 부작용은 개발자가 필요한 것을 생각하기보다는 일반적인 import line을 복사하여 붙여 넣는 것입니다.


에서 DDD 책

구현의 기반이되는 개발 기술에서 모듈 리팩토링 작업을 최소화하는 방법을 찾으십시오. Java에서는 개별 클래스로 가져 오기를 피할 수는 없지만 패키지는 한 번에 전체 패키지를 가져올 수 있으며, 패키지 이름이 변경되는 노력을 줄이면서 패키지가 응집력이 높은 단위라는 의도를 반영합니다.

그리고 그것이 로컬 네임 스페이스를 어지럽히면 오류가 아닙니다. 패키지의 크기를 비난하십시오.


가장 중요한 것은 가져 오기 java.awt.*를 통해 프로그램이 향후 Java 버전과 호환되지 않을 수 있다는 것입니다.

"ABC"라는 클래스가 있다고 가정하고 JDK 8을 사용하고 있으며 import를 가져옵니다 java.util.*. 이제 Java 9가 나오고 java.util우연히 "ABC"라고 불리는 새로운 클래스의 패키지 있다고 가정하십시오 . 컴파일러가 "ABC"라는 이름을 가진 자신의 클래스 또는 새 클래스를 의미하는지 알 수 없기 때문에 이제 프로그램이 Java 9에서 컴파일되지 않습니다 java.awt.

java.awt실제로 사용 하는 클래스 만 명시 적으로 가져 오면 문제가 발생하지 않습니다 .

자원:

자바 수입


양쪽 모두에서 유효한 모든 포인트 중에서 와일드 카드를 피해야하는 주된 이유를 찾지 못했습니다. 코드를 읽고 모든 클래스가 무엇인지 또는 언어의 정의가 언어 또는 언어에 없는지 직접 알고 싶습니다. 파일이있는 위치 둘 이상의 패키지를 가져 오면 * 인식하지 못하는 클래스를 찾기 위해 모든 패키지를 검색해야합니다. 가독성은 최고이며, 코드 를 읽을 때 IDE가 필요 하지 않아야한다는 데 동의 합니다.


  • 컴파일러가 *를 구체적인 클래스 이름으로 자동 대체하므로 런타임 영향은 없습니다. .class 파일을 디 컴파일하면을 볼 수 없습니다 import ...*.

  • C # 패키지 이름 만 사용할 수 있으므로 항상 * (암시 적으로)를 사용합니다 using. 클래스 이름을 전혀 지정할 수 없습니다. Java는 C # 다음에이 기능을 소개합니다. (자바는 여러 측면에서 매우 까다 롭지 만이 주제를 넘어선 것입니다).

  • Intellij Idea에서 "가져 오기 구성"을 수행하면 동일한 패키지의 여러 가져 오기가 *로 자동 대체됩니다. 이 기능은 끌 수 없으므로 필수 기능입니다 (임계 값을 늘릴 수 있음).

  • 수락 된 답변으로 표시된 사례가 유효하지 않습니다. *가 없으면 여전히 같은 문제가 있습니다. * 사용 여부에 관계없이 코드에 pakcage 이름을 지정해야합니다.


레코드의 경우 : 가져 오기를 추가 할 때 종속성도 표시합니다.

동일한 네임 스페이스의 클래스를 제외하고 파일의 종속성이 무엇인지 신속하게 확인할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/147454/why-using-a-wild-card-with-a-java-import-statement-bad



반응형