2009-05-13 4 views
1

나는 처음에는 자바 사람이 아니지만 표면에 나타나는 것이 수입품 수입 방식과 모순되는 것을 보았습니다. 수입품 구현

당신이 파일이이 파일에 당신이 당신의 주요 기능을 말해봐 당신은 또한 푸 푸 또한 패키지에 존재 지금 다른 구현을 클래스 을 정의했습니다. 귀하의 기능에서 두 버전을 모두 사용하고자한다고 가정하십시오.

Foo을 패키지에서 가져올 수 없습니다. 예 : import mypackage.Foo;

이로 인해 파일에서 로컬로 정의 된 클래스와 충돌하게되므로 컴파일 타임에 오류가 발생합니다.

무엇을 할 수 있습니까?는 전체 패키지를 가져옵니다. 즉, import mypackage. *;

이 작동하며 로컬 의 사용됩니다 간단한 이름을 사용하여 정규화 된 이름을 사용하여 에 액세스 할 수 있습니다. 내가보기에 불일치가있는 것은 전자가 오류를 생성하는 동안 (클래스를 가져 왔고 가져 오기의 유일한 목적은 완전한 이름과 달리 단순한 이름을 사용할 수 있다는 것입니다) 후자는 경고.

두 경우 모두 경고가 발생한다고 생각 했겠죠. 예를 들어, 두 곳에서 정의 된대로 잘못된 클래스를 사용하거나 간단한 이름을 사용하면 중복되는 import 문이 로컬에서 정의 된 클래스로 해결됩니다. 수입 한 것이 아닙니다.

제 질문은 다음과 같습니다.이 방법으로 구현 된 근본적인 이유가 있습니까?

예. 이상한 사례입니다. 이해합니다.

+1

작은 노트 : 가져 오기 문은 패키지 이름을 입력하지 않아도 사용되며 다른 작업은 수행하지 않습니다. 바로 가기입니다. 항상 완전한 이름을 사용하면 가져 오기가 전혀 필요하지 않습니다. –

+0

필자는 패키지가 존재하는 이유를 이해합니다. 가져온 패키지의 클래스를 참조 할 수 있고 경고가 전혀없는 것처럼 보입니다. 그 이름을 가진 클래스가 로컬에 정의되어 있는지 여부에 관계없이 오류가 있습니다. 로컬로 정의 된 클래스와 같은 이름의 클래스를 명시 적으로 가져올 때. 두 경우 모두 import 문은 해당 클래스에 대해 중복되지만 아직 수익률과 오류가 하나가 아닌 다른 것은 수행하지 않습니다. – Stinomus

답변

9

mypackage. *;을 (를) 가져 오지 않고도 정규화 된 이름을 사용하여 Foo에 액세스 할 수 있습니다.

경고 : 위험한 일은 없습니다. 모호한 것을 사용하지 않습니다.

+0

로컬로 정의 된 클래스는 후자의 예에서 조용한 환경 설정을 가지고 있습니다. 앞의 예제의 동작이 두 경우 모두 가져 오기가 중복되는 것처럼 일관성이 있어야합니다. – Stinomus

+0

사용되지 않거나 중복 된 가져 오기에 대한 경고가있을 경우 모든 컴파일 작업에서 수백 가지 경고 메시지가 표시됩니다. 또한 누구도 요즘 손으로 수입품을 씁니다. – alamar

+0

잘 사용되지 않고 중복되는 것은 실제로 동일한 것이 아닙니다. 로컬 정의 클래스 중 하나와 동일한 이름의 클래스가있는 패키지를 가져 오는 많은 경우가 있습니까? – Stinomus

1

수입품에 관해서는, mypackage에있는 그 밖의 모든 것이 필요할지도 모른다. 경고가 있었다면이를 피하는 것이 어려울 수 있습니다. 즉, mypackage에서 사용하는 다른 모든 수업 등을 완전히 수료해야합니다. mypackage의 버전 1에 Foo가 포함되지 않았기 때문에 충돌이 발생하지 않았으므로 경고를 발행 할 이유가 없었습니다. 버전 2에는 Foo가 포함되어 있지만 물론 프로그램에서 액세스하려는 Foo가 아닙니다. 따라서 컴파일러에서 "import package. *"충돌에 대해 경고하면 "import package. *"가 잠재적으로 덜 상위 호환성을 갖습니다.

3

위의 대답에서 알 수 있듯이 수입은 다른 패키지의 Foo과 관련하여 아무런 효과가 없습니다. 에 관계없이 당신이 수입 여부에 관계없이 짧은 클래스 이름을 통해 그 다른 Foo를 참조 할 수 없습니다 당신은 정규화 된 클래스 이름을 통해 그것을 참조하십시오.

은 개념적으로는 "수입이 아닌 모든 충돌 mypackage에서 클래스를"아마도 " mypackage에서 수입하는 모든 클래스"로 반드시 import mypackage.*의 생각하지만, 할 수 있습니다. 나는 Sun의 컴파일러 구현이 어떻게되는지 모르지만 mypackage와 일치하지 않기로 결정할 수 있습니다. 와일드 카드의 일부로 Foo (따라서 가져 오지 않음) 코드는 동일한 방식으로 작동합니다.

가져 오기는 짧은 클래스 이름에서 완전한 클래스 이름으로 별칭을 설정하는 것입니다 (예 : Datejava.util.Date으로 해석 할 때). 충돌하는 클래스를 가져 오는 것과 같이 완전히 중복되는 작업을 수행하면 경고 메시지가 표시 될 것으로 예상됩니다. 그러나 *을 사용하여 전체 패키지를 가져 오는 경우 컴파일러가 클래스 이름 중 하나가 충돌한다는 불만을 나타냅니다. 이것은 실제로 실제로 일어날 것이고, 무해한 99 % 이상의 시간에, 당신이이 경고와 다른 경고에 관심을 덜 기울일 수있는 지점으로 "울프 울프 소년"증후군을 유발할 것입니다. 그냥 그들에게 폭격당하는 것에 익숙해 져야합니다.

그런데 java.util.*java.sql.*을 모두 가져 오는 경우 허용되며 허용되지 않으며 경고가 표시되지 않습니다. 그런 다음 Date (로컬 패키지의 해당 클래스 제외)을 참조하려고하면 이름이 모호하므로 컴파일 오류가 발생합니다.

+2

JVM은 가져 오기를 전혀 수행하지 않습니다. 내부적으로는 항상 정규화 된 클래스 이름을 사용합니다. 가져 오기는 컴파일러에만 관련이 있습니다. –

+2

수입은 개발자와 관련이 있습니다. 수업을 가져 와서 짧은 이름으로 참조하고 직접 입력 할 수 있기 때문입니다. – duffymo

+0

둘 다 같은 행동을하지 않아야하는 이유가 있습니까? – Stinomus

1

"import p. *"는 "현재 파일에서 이름을 확인할 수 없을 때 패키지 p에서 해결하려고 시도하십시오"라는 의미로 생각할 수 있습니다. 컴파일러는 p에있는 모든 항목을 가져 오기 명령문을 볼 때 가져 오지 않습니다. 대신 직접 컴파일 단위에서 확인할 수없는 이름을 찾으면 p (및 import ... * 문에 명명 된 다른 패키지)을 찾습니다.