Java: 서브패키지 가시성?
에는 두 .odp.proj
★★★★★★★★★★★★★★★★★」odp.proj.test
이 두 패키지의 클래스에만 표시되도록 하는 특정 메서드가 있습니다.★★★★★★★★★★★★★★★★★★★?
편집: Java에 서브패키지의 개념이 없는 경우, 이 문제를 해결할 방법이 있습니까?저는 테스터와 그 패키지의 다른 멤버에게만 제공하고 싶은 방법이 있습니다.그냥 다 같은 포장에 넣어야 하나요?광범위한 반사를 사용하시겠습니까?
그럴수는 없어요. 때문에 에서는 서브패키지의 개념이 .odp.proj
★★★★★★★★★★★★★★★★★」odp.proj.test
츠키다
패키지 이름을 보면 이 응용 프로그램이 장치 테스트용임을 알 수 있습니다.하고 싶은 를 같은 패키지에 것입니다(이 유닛테스트 ).odp.proj
하다그래서 당신은 당신의 수업을src/odp/proj
와 테스트 코드(「 ★★★★★★★★★★★★★★★★★★ 。test/odp/proj
.
Java에는 "패키지" 액세스 수식자가 있습니다. 이 수식자는 아무것도 지정되지 않은 경우 기본 액세스 수식자입니다(즉,공적인수식자를 하면 "package" 할 수 있습니다.odp.proj
는 메서드에 액세스할 수 있습니다.에서는 어떤 할 수 점에 하시기 바랍니다.액세스 수식자는 (제한적인 보안 매니저가 존재하지 않는 한) 시사적인 것일 뿐입니다.
이 답변의 대부분은 Java에는 서브패키지라는 것이 없다고 기술되어 있습니다만, 그것은 정확하지 않습니다.이 용어는 Java Language Specification(JLS; Java 언어 사양)에 정의되어 있으며, 사양의 초기 버전부터 사용되고 있습니다.
Java 15 JLS:
패키지의 멤버는 서브패키지와 패키지의 모든 컴파일 단위로 선언된 모든 최상위 클래스 유형 및 최상위 인터페이스 유형입니다.
예를 들어 Java SE Platform API에서 다음 작업을 수행합니다.
- ' ' ''
java
는 서브패키지 「」를 가지고 있습니다.awt
,applet
,io
,lang
,net
, , , , 입니다.util
컴파일 유닛은 없습니다.- ' ' ''
java.awt
에는 has has이이packpackpackpackpackpackageageageageageageageageageageage라는 이름의 .image
클래스 및 인터페이스 유형의 선언을 포함하는 다수의 컴파일 유닛을 포함합니다.
서브패키지 개념에는 패키지와 클래스/인터페이스 간에 이름 지정 제약이 적용되는 것과 같이 실질적인 의미가 있습니다.
패키지에 같은 이름의 멤버가 2개 포함되어 있지 않거나 컴파일 시 오류가 발생할 수 있습니다.
다음은 몇 가지 예입니다.
- '''가
java.awt
image
「이라고 하는 이름의 클래스 또는 인터페이스 타입의 선언을 수 없습니다(하지 않습니다).image
.- 「 」라고 하는 의 패키지가 .
mouse
타입 " " " " " " 입니다.Button
(은) (라고 수 )mouse.Button
name)을 하지 않습니다.mouse.Button
★★★★★★★★★★★★★★★★★」mouse.Button.Click
.- if
com.nighthacks.java.jag
인 패키지는 할 수 없습니다.완전 수식 이름이 다음 중 하나인 패키지는 사용할 수 없습니다.com.nighthacks.java.jag
★★★★★★★★★★★★★★★★★」com.nighthacks.java.jag.scrabble
.
단, 이 명명 제한은 언어에 의해 서브패키지에 제공되는 유일한 의미입니다.
패키지의 계층적 명명 구조는 기존의 방식으로 관련 패키지를 구성하는 데 편리하도록 의도되었지만, 패키지에 선언된 최상위 유형과 동일한 이름의 하위 패키지를 갖는 패키지에 대한 금지 외에는 의미가 없습니다.
를 들어, 「」라고 하는 이름의 사이에는 특별한 .
oliver
또 다른 패키지가 있습니다.oliver.twist
「」라고 하는 이름의 또는 「 」evelyn.wood
★★★★★★★★★★★★★★★★★」evelyn.waugh
, 패키지 , 「」, 「」,oliver.twist
에서는 패키지 되지 않았습니다.oliver
을 사용하다
이런 맥락에서 우리는 그 질문 자체에 답할 수 있다.패키지와 그 서브패키지 또는 부모패키지의 2개의 다른 서브패키지 사이에는 특별한 액세스 관계가 없기 때문에 언어 내에서는 메서드를 요청된 방법으로2개의 다른 패키지에 표시할 수 없습니다.또, 다른 패키지로부터의 액세스를 제한할 수도 없습니다.이것은 문서화되어 의도적인 설계 결정입니다.
를 포함한다)를 하거나 둘 중 입니다.odp.proj
★★★★★★★★★★★★★★★★★」odp.proj.test
메서드에 수 를 프라이빗하게 수 가시성패키지에 할 가 있는 (는 지정된 메서드에 액세스할 수 있습니다.또는 메서드는 패키지 프라이빗(기본 가시성)으로 할 수 있습니다.패키지에 직접 액세스 할 필요가 있는 모든 코드는 메서드와 같은 (서브)에 넣을 필요가 있습니다.
테스트 사용 사례에 대해서는 자바에서 표준적인 프랙티스는 타입의 테스트 코드를 소스 코드와 같은 패키지에 넣어 파일 시스템의 다른 위치에 두는 것입니다.예를 들어, Maven 빌드 툴과 Gradle 빌드 툴에서는 소스 파일을 삽입하는 것이 관례입니다.src/main/java/odp/proj
및 테스트파일을 합니다.src/test/java/odp/proj
은 「」로 odp.proj
「」, 「」, 「」만,src
파일은 프로덕션 아티팩트에 포함됩니다. 테스트 파일은 빌드 시 프로덕션 파일을 확인하는 데만 사용됩니다.이 설정을 사용하면 테스트 코드는 테스트 중인 코드의 패키지 개인 코드 또는 보호된 코드에 자유롭게 액세스할 수 있습니다. 이는 테스트 코드가 동일한 패키지에 포함되기 때문입니다.
테스트/프로덕션 케이스가 아닌 서브패키지 또는 형제 패키지 간에 코드 공유를 원하는 경우, 일부 라이브러리에서 사용하던 솔루션 중 하나는 공유 코드를 공개하는 것이지만 내부 라이브러리 전용으로 문서화하는 것입니다.
은 특별한 .odp.proj
★★★★★★★★★★★★★★★★★」odp.proj.test
어느쪽이든 상관없습니다.
경우,odp.proj.test
, 한 패키지 이름패키지 이름)을 할 수 .odp.proj
및 Eclipse net Netbeans 등등IDE 、 별 ).(((((((((((((((((((((((((((((((((((( ( ( ( )를 만듭니다.src/main/java/odp/proj
★★★★★★★★★★★★★★★★★」src/test/java/odp/proj
JUnit를 사용하다
는, 「IDE」의 에 관한 합니다.odp.proj
존재하지 않는 테스트 방법에 적합한 폴더를 만듭니다.
IntelliJ에서 이렇게 하면 소스 트리는 다음과 같습니다.
src // source root
- odp
- proj // .java source here
- test // test root
- odp
- proj // JUnit or TestNG source here
다른 사람들이 설명했듯이 자바에는 "서브패키지"와 같은 것은 없습니다.즉, 모든 패키지는 격리되어 부모로부터 아무것도 상속받지 않습니다.
다른 패키지에서 보호된 클래스 멤버에 쉽게 액세스할 수 있는 방법은 클래스를 확장하고 멤버를 재정의하는 것입니다.
를 들어, 에 액세스 , 「 」를 참조해 주세요.ClassInA
a.b
:
package a;
public class ClassInA{
private final String data;
public ClassInA(String data){ this.data = data; }
public String getData(){ return data; }
protected byte[] getDataAsBytes(){ return data.getBytes(); }
protected char[] getDataAsChars(){ return data.toCharArray(); }
}
한 메서드를 .ClassInA
:
package a.b;
import a.ClassInA;
public class ClassInAInB extends ClassInA{
ClassInAInB(String data){ super(data); }
@Override
protected byte[] getDataAsBytes(){ return super.getDataAsBytes(); }
}
그러면 다른 패키지의 클래스 대신 재정의 클래스를 사용할 수 있습니다.
package a.b;
import java.util.Arrays;
import a.ClassInA;
public class Driver{
public static void main(String[] args){
ClassInA classInA = new ClassInA("string");
System.out.println(classInA.getData());
// Will fail: getDataAsBytes() has protected access in a.ClassInA
System.out.println(Arrays.toString(classInA.getDataAsBytes()));
ClassInAInB classInAInB = new ClassInAInB("string");
System.out.println(classInAInB.getData());
// Works: getDataAsBytes() is now accessible
System.out.println(Arrays.toString(classInAInB.getDataAsBytes()));
}
}
이 기능은 확장 클래스(상속)에 표시되는 보호된 멤버에만 적용되며, 동일한 패키지 내의 하위/확장 클래스에만 표시되는 패키지 개인 멤버에는 적용되지 않습니다.이게 도움이 됐으면 좋겠네요!
편집: Java에 서브패키지의 개념이 없는 경우, 이 문제를 해결할 방법이 있습니까?저는 테스터와 그 패키지의 다른 멤버에게만 제공하고 싶은 방법이 있습니다.
이 방법을 표시하지 않는 동기에 따라 다르지만 테스트(또는 다른 내부)만을 목적으로 하는 것으로 퍼블릭인터페이스를 오염시키지 않는 유일한 이유라면 다른 퍼블릭인터페이스에 넣어 '숨겨진' 방식의 소비자에게 그 인터페이스를 사용하도록 하겠습니다.그것이 다른 사람들이 인터페이스를 사용하는 것을 막지는 못하지만, 나는 당신이 해야 할 이유를 모르겠다.
유닛 테스트의 경우 및 로트를 다시 작성하지 않고 가능한 경우 권장사항에 따라 동일한 패키지를 사용하십시오.
메서드 앞에 액세스 수식자를 붙이지 않고 패키지 개인이라고 합니다.
음음
package odp.proj;
public class A
{
void launchA() { }
}
package odp.proj.test;
public class B
{
void launchB() { }
}
public class Test
{
public void test()
{
A a = new A();
a.launchA() // cannot call launchA because it is not visible
}
}
PackageVisible 포함도우미 클래스 및 PackageVisible 전에 비공개로 유지Helper Factory frozen, launchA를 호출할 수 있습니다(PackageVisible).Helper ) 메서드(어디서나):
package odp.proj;
public class A
{
void launchA() { }
}
public class PackageVisibleHelper {
private final PackageVisibleHelperFactory factory;
public PackageVisibleHelper(PackageVisibleHelperFactory factory) {
super();
this.factory = factory;
}
public void launchA(A a) {
if (factory == PackageVisibleHelperFactory.INSTNACNE && !factory.isSampleHelper(this)) {
throw new IllegalAccessError("wrong PackageVisibleHelper ");
}
a.launchA();
}
}
public class PackageVisibleHelperFactory {
public static final PackageVisibleHelperFactory INSTNACNE = new PackageVisibleHelperFactory();
private static final PackageVisibleHelper HELPER = new PackageVisibleHelper(INSTNACNE);
private PackageVisibleHelperFactory() {
super();
}
private boolean frozened;
public PackageVisibleHelper getHelperBeforeFrozen() {
if (frozened) {
throw new IllegalAccessError("please invoke before frozen!");
}
return HELPER;
}
public void frozen() {
frozened = true;
}
public boolean isSampleHelper(PackageVisibleHelper helper) {
return HELPER.equals(helper);
}
}
package odp.proj.test;
import odp.proj.A;
import odp.proj.PackageVisibleHelper;
import odp.proj.PackageVisibleHelperFactory;
public class Test {
public static void main(String[] args) {
final PackageVisibleHelper helper = PackageVisibleHelperFactory.INSTNACNE.getHelperBeforeFrozen();
PackageVisibleHelperFactory.INSTNACNE.frozen();
A a = new A();
helper.launchA(a);
// illegal access
new PackageVisibleHelper(PackageVisibleHelperFactory.INSTNACNE).launchA(a);
}
}
언급URL : https://stackoverflow.com/questions/1967229/java-subpackage-visibility
'source' 카테고리의 다른 글
서비스 워커 이벤트가 호출되고 있음을 App.vue에 알리다 (0) | 2022.08.30 |
---|---|
C++에 typedef 키워드와 동등한 Java 또는 방법론이 있습니까? (0) | 2022.08.30 |
Apple에서 정적 라이브러리 결합 (0) | 2022.08.30 |
Vuetify Switch를 사용하여 Vuex 상태 변경 (0) | 2022.08.29 |
VueJS/nuxt 'state'는 store/store.js의 개체를 반환하는 메서드여야 합니다. (0) | 2022.08.29 |