Java 9에서 패키지와 모듈이 별도의 개념 인 이유는 무엇입니까?


21

Java 9에는 패키지 외에도 모듈이 있습니다. 일반적으로 언어에는 둘 중 하나가 있습니다. 그리고 대부분의 프로그래머 두 용어를 동의어로 인식 합니다. 모듈은 패키지 위에 구축되어 기본 요소로 취급합니다. 복합 패턴은 프리미티브 및 복합 재료를 균일하게 처리 할 것을 제안합니다. 그렇지 않으면 나쁜 일이 일어날 것입니다. 예를 들어, Valhalla 프로젝트를보고 기본 (값) 및 참조 유형에 공통 수퍼 타입을 개조하려고합니다.

모듈과 패키지는 의미 상 분리 된 개념을 나타 냅니까? 모든 언어에 대해 두 가지를 모두 갖는 것이 합리적이라는 것을 의미합니다 (문제의 분리). 아니면 Java는 이전 버전과의 호환성에 대한 찬사를 가지고 있어야합니까?

기존 개념을 보강하는 대신 새로운 개념을 도입하는 이유는 무엇입니까?


JSR 376 : 프로젝트 내에서 구현 "자바 플랫폼 모듈 시스템" 지그 소 퍼즐 .

SOTMS 에 따르면

모듈은 명명 된 자체 설명 코드 및 데이터 모음입니다. 코드는 유형, 즉 Java 클래스 및 인터페이스를 포함하는 패키지 세트로 구성됩니다. 데이터에는 리소스 및 기타 종류의 정적 정보가 포함됩니다.

JLS는 패키지 정의를 신중하게 피 합니다 . 에서 위키 백과 :

Java 패키지는 Java 클래스를 Modula 모듈과 유사한 네임 스페이스로 구성하여 Java로 모듈 식 프로그래밍을 제공하는 기술입니다.

Wikipedia를 인용하는 것은 나쁜 습관이지만 일반적인 이해를 반영한다는 것을 알고 있습니다. 에서 입력 모듈 프로그래밍에 대한 :

패키지 라는 용어 는 모듈 대신에 사용됩니다 (Dart, Go 또는 Java에서와 같이). 다른 구현에서, 이것은 별개의 개념입니다. 파이썬에서 패키지는 모듈의 모음이며, 향후 Java 9에서는 새로운 모듈 개념 (향상된 액세스 제어 기능을 가진 패키지 모음)의 도입이 계획되어 있습니다.


3
여기에 많은 질문이있는 것 같아요? 1) 모듈과 패키지는 동일한 의미 론적 아이디어입니까? 2) (1이 아닌 경우), jigsaw스타일 모듈 은 패키지에 비해 기술적 개선입니까? 3) (1이 아니라면 2) Java는 단순히 이전 버전과의 호환성을 위해 개념을 모두 유지 합니다 . 이러한 질문 중 일부는 대답이 가능하고 일부는 주로 의견 중심입니다. 나는 설명을 단순화하는 편집이 순서대로 있다고 생각합니다.
Tersosauros

1
@Tersosauros "일부"질문은 주제를 벗어난 것으로 분류했지만 어느 것이 어떤 것인지 표시하지 않았습니다. 나는 단지 하나의 질문으로 본다 (1). 다른 것은 자동으로 해결됩니다. 자바와의 호환성은 문제가되지 않습니다. 따라서 패키지 디자인 결함을 패치하기위한 Java 도입 모듈 또는 두 가지 개념은 완전히 분리 된 관심사입니다. 혼동은 이름이 잘못되어 발생합니다.
user2418306

1
질문을 더 명확하게하고 싶습니다. 그러나 대답 할 수없는 부분을 이해해야합니다. 한 부분 만 있다고 생각할 때.
user2418306

아, 혼란을 이해합니다. 나는 질문 # 1 대답 할 수 있다고 생각합니다 (그 대답은 "예, 아니오"입니다-# 3이 나오는 곳). 나는 # 3에 동의한다. 분명히 자바는 언어 키워드가 무엇인지 package/ 행동 / 의미를 바꾸려고하지 않으며, JRE에서 클래스 경로 시스템으로 바뀔 수도 없다. 질문 # 2 I 느낌은 주로 의견 지향 (이 없습니다 답할 수 있지만, 내 대답하고 다른 사람의이 다를 수 있으며, 둘 다 우리의 필요는 잘못된 것입니다).
Tersosauros

1
먼저 명확한 질문을 한 다음 보조 자료를 제공하십시오.
Jay Elston

답변:


22

모듈 의 개념 은 해당 개념의 인스턴스화와 다릅니다.

Java에는 항상 모듈이 있습니다. 메소드는 모듈이며 클래스도 패키지입니다. 모듈은 내부 세부 정보가 숨겨져 있고 계약에 따라 다른 모듈과 통신하는 조직 단위입니다. 예를 들어, 메서드에는 숨겨진 내부 (코드 및 로컬 변수)와 계약 (매개 변수 및 반환 형식)이 있으므로 모듈입니다. 모듈은 하위 레벨 모듈로 구성 될 수 있습니다 (예 : 클래스에 메소드 포함).

핵심 Java (9 이전)에서 누락 된 것은 배포 가능한 모듈입니다. 위의 모든 종류의 모듈은 복사 할 수있는 배치 가능한 장치가 아닙니다. Java에는 JAR 파일이라는 배치 가능한 아티팩트가 있지만 캡슐화 또는 계약이 없기 때문에 모듈이 아닙니다. 런타임시 JAR 파일이 모두 사라지고 단일 "classpath"로 병합됩니다.

OSGi 는 1998 년에 "번들"이라는 개념으로 배포 가능한 모듈의 부족을 해결했습니다. 이들은 실제 JAR 파일이며 패키지를 포함하지만 OSGi는 런타임 시스템과 함께 추가 메타 데이터를 정의하여 해당 레벨에서 캡슐화 및 계약을 지원합니다.

Java 9는 OSGi와 유사한 방식으로 배포 가능한 모듈이없는 문제를 해결합니다. 아마도 OSGi가 존재하고 작동하기 때문에 이것은 완전히 불필요하지만 완전히 다른 토론입니다 ...

불행히도 Java 9는 새로운 모듈 개념을 "모듈"이라고 명명함으로써 물을 혼동합니다. 이것은 메소드, 클래스 및 패키지가 모듈이되는 것을 멈추는 것을 의미하지는 않습니다! J9 "모듈"은 모듈 개념 의 또 다른 인스턴스입니다 . OSGi 번들과 마찬가지로 J9 모듈은 패키지로 구성되며 복사 할 수있는 물리적 아티팩트 (일반적으로 JAR 파일)입니다. 런타임 시스템은이를 이해하고 재조정합니다.

요약 : 예 J9 모듈과 패키지는 의미 상 분리 된 개념입니다. 분명히 Java는 이전 버전과의 호환성을 위해 기존 패키지 개념을 유지해야합니다. "package"라는 단어는 다른 언어 나 RPM과 같은 패키지 관리 시스템과는 Java에서 상당히 다르게 사용됩니다. 새로운 J9 모듈 (및 OSGi 번들)은 Java 패키지보다 RPM 패키지와 훨씬 유사합니다.


패키지가 귀하의 모듈 정의를 충족하지 않습니다. 캡슐화가 약하고 다른 패키지를 집계하고 가시성을 개선 할 수있는 수단이 없기 때문에. 클래스는 중첩 클래스 또는 필드를 포함 할 수 있습니다. 메소드는 클로저를 포함하거나 다른 메소드를 호출 할 수 있습니다. 패키지는 다른 패키지와 "통신"할 수 없습니다.
user2418306

동의하지 않습니다. 패키지에는 정보가 숨겨져 있습니다 (기본 액세스 유형, 메소드 및 필드, 일명 패키지 전용). 패키지 내의 코드는 다른 패키지의 코드를 호출 할 수 있기 때문에 패키지는 확실히 "통신"합니다. 이것은 계약, 즉 다른 패키지의 공개 유형 및 방법에 대해 수행됩니다.
닐 바틀렛

동일한 수준 에서 모듈 식 아티팩트를 집계하는 기능 (예 : 클로저를 포함하는 메소드, 중첩 클래스를 포함하는 클래스)은 모듈 정의의 일부를 구성하지 않습니다. 이것을 모듈 정의의 필수 부분으로 간주하면 "Java 9 모듈"도 모듈이 아닙니다.
닐 바틀렛

패키지에 정보가 숨겨져 있음을 부정하지 않습니다 . 나는 충분하지 않다고 말했다. import패키지를 결합 할 수 있습니다. 그러나 일등 시민으로서 패키지를 구조화 할 수있는 방법은 없습니다. 이러한 단점 (및 OSGi의 제한 사항)은 JSR 376에 설명되어 있습니다.
user2418306

Java 9 모듈이 모듈이 아닌 이유를 자세히 설명 할 수 있습니까 ?
user2418306

10

대부분 가정이나 머리카락 쪼개기 / 보충 등이있을 수 있지만 대답 할 때 위험에 처하게하겠습니다.

그들은 같은 것입니까? 음, 아니오

에서 "자바 9 모듈화"에 대한이 JavaWorld 기사 :

모듈 식 솔루션으로 패키지

패키지는 Java 프로그래밍 환경에 추상화 레벨을 추가하려고합니다. 고유 한 코딩 네임 스페이스 및 구성 컨텍스트를위한 기능을 제공합니다. 그러나 안타깝게도 패키지 규칙이 우회되어 위험한 컴파일 타임 커플 링 환경으로 이어지는 경우가 많습니다.

@ user2418306 (OP)이 암시 한 것처럼 " 모듈은 올바르게 수행 된 패키지입니다 " . Java의 모듈과 패키지 (Java 9부터)는 의미 적 으로 OP와 마찬가지로 의미 상 동일합니다. 즉, 그들은 미리 컴파일 된 JVM 바이트 코드의 모음입니다 다른 메타 데이터와 함께 - 기본적으로 , 그들이 도서관 .

차이점은 무엇입니까?

그러나 차이점은 각각의 메타 데이터 에 있습니다. Java package매니페스트 또는 JAR 매니페스트는 종종 라이브러리 개발자가 유지 관리하지 않으며 JAR / 패키지가 제공하는 내용에 대한 확실한 계약을 제공하지도 않습니다. 여기에 설명 된 대로 (JavaWorld 기사 다시) :

JAR 파일이 모듈 식으로 충분하지 않습니까?

JAR 파일 및 이들이 작동하는 배치 환경은 사용 가능한 많은 레거시 배치 규칙에서 크게 개선됩니다. 그러나 JAR 파일은 .jar 매니페스트에 숨겨져 거의 사용되지 않는 버전 번호를 제외하고 고유 한 고유성을 갖지 않습니다. JAR 파일 및 선택적 매니페스트는 Java 런타임 환경에서 모듈화 규칙으로 사용되지 않습니다. 따라서 파일에있는 클래스의 패키지 이름과 클래스 경로에 대한 참여는 런타임 환경에 모듈성을 제공하는 JAR 구조의 유일한 부분입니다.


다른 언어 / 환경 등에 대한 불만

이 기사에서 논의 된 또 다른 영역 은 빌드 프로세스의 일부로 종속성을 관리하는 Maven 과 같은 시스템 입니다. 에서 아파치 메이븐 사이트의 페이지 :

의존성 관리 :

Maven은 JAR 및 기타 종속성의 중앙 저장소를 사용하도록 권장합니다. Maven은 프로젝트 클라이언트가 Perl의 CPAN과 같은 중앙 JAR 저장소에서 프로젝트를 빌드하는 데 필요한 JAR을 다운로드하는 데 사용할 수있는 메커니즘을 제공합니다. 이를 통해 Maven 사용자는 프로젝트 전체에서 JAR을 재사용하고 프로젝트 간 통신을 장려하여 이전 버전과의 호환성 문제를 해결할 수 있습니다.

마치 내가 있었던 것처럼 미래에 대해 이야기

으로 해당 페이지가 언급 (예 : Perl과 같은) 다른 언어 (같은 패키지 저장소가 CPAN을 ). 이것은 지난 수십 년 동안 점점 증가하는 추세입니다 (나는 어떤 증거도없이 느낌이 들기 때문에). 루비의 같은 도구 보석 , 파이썬의 PyPi 하고, 노드 패키지 관리자 ( npm) 이시 빌드가 오른쪽과 환경 (중 개발, 빌드, 테스트 또는 런타임 등) 구성의 일관성있는 방법으로 제공하는 물건 (패키지, 모듈 보석, 기즈모 등). 아이디어는 (I 느낌)했다 " 빌린 " 데비안의 같은 리눅스 (Linux®) 분배 시스템에서 APT , 레드햇의rpm등이 있습니다 (물론 적어도 세대를 진화 시켜서 이러한 것들을 모두 더 멋지게 만들었습니다.)


Java 모듈 은 이미 수행 할 수없는 것을 추가 할 필요는 없지만 종속성 / 패키지 관리 및 자동화 된 빌드 환경을위한 툴링을 훨씬 쉽게 만듭니다. 그것이 모듈을 "더 좋게"만들 었는지 여부에 대해서는 말하기를 거부합니다. :피


1
기사는 1 년 전이지만 아직 사용되지 않습니다. 버전 관리가 모듈의 기본 특성 인 방법에 대해 설명합니다. 퍼즐 모듈에는 버전 정보가 없습니다. 최종 사용자에 대한 종속성 관리 영역에는 변화가 없습니다. 빌드 도구의 경우 실제로는 훨씬 어려워집니다. 그들이 classpath와의 병렬 현실을 지원해야하기 때문에 modulepath. 그리고 유닛 테스트를 지원하기 위해 후프를 뛰어 넘습니다. 두 개념이 사물 수집을 나타 내기 때문에 메타 데이터가 너무 대담하기 때문에 두 개념이 동등하다는 것을 전제로하십시오. 또한 중간에 갑자기 항아리를 패키지로 대체했습니다.
user2418306

나는 " 두 개념이 동등하다 " 고 말하지 않았으며 , "의미 적으로 같은 것"이라고 말했습니다. 또한, 당신은 내가하는 대답 때문에 질문 편집 한 특별히 JSR-376 언급을 뿐만에 반대 퍼즐 앞서 말한 것입니다 : - /
Tersosauros

퍼즐은 JSR-376을 구현합니다. 질문은 여전히 ​​둘 다에 연결되어 있으므로 아무런 피해도 없었습니다. 사전은 동등성을 동일한 의미를 갖는 품질 또는 상태로 정의합니다. 그리고 의미 적으로-의미와 관련하여. 죄송합니다. 여기에서 잘못된 세부 정보에 대해 놀랍게 생각하고 있습니다. 당신은 그것들이 동등하다고 말했습니다. 그러나 당신은 어떤 추론도 제공하지 않았습니다. 대신 패키지와 jar가 모듈이 아닌 방법을 설명하는 기사를 참조하십시오. 그러나 다가오는 모듈도 기사의 모듈이 아닙니다. 동등성을 주장하고 2 (3)의 차이를 제공하는 것은 자기 모순입니다.
user2418306

질문에 대한 대답은 예와 아니오 일 수 없습니다. 두 개념이 의미 상 동등하거나 그렇지 않습니다. 내 의견을 lomotomize하지 말고 원래 질문으로 돌아가십시오. 언어에 두 가지 개념이 모두 필요합니까 아니면 Java 레거시 특정 문제입니까? 설명이 필요하면 기꺼이 도와 드리겠습니다.
user2418306
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.