プロジェクトに と の 2 つのパッケージがodp.projありodp.proj.testます。これら 2 つのパッケージのクラスだけに表示したい特定のメソッドがあります。これどうやってするの?
編集: Javaにサブパッケージの概念がない場合、これを回避する方法はありますか? テスターとそのパッケージの他のメンバーだけが利用できるようにしたい特定のメソッドがあります。すべてを同じパッケージに入れる必要がありますか? 広範な反射を使用しますか?
プロジェクトに と の 2 つのパッケージがodp.projありodp.proj.testます。これら 2 つのパッケージのクラスだけに表示したい特定のメソッドがあります。これどうやってするの?
編集: Javaにサブパッケージの概念がない場合、これを回避する方法はありますか? テスターとそのパッケージの他のメンバーだけが利用できるようにしたい特定のメソッドがあります。すべてを同じパッケージに入れる必要がありますか? 広範な反射を使用しますか?
できません。Java にはサブパッケージの概念がないためodp.proj、 とodp.proj.testは完全に別のパッケージです。
パッケージの名前は、ここにあるアプリケーションが単体テスト用であることを示唆しています。使用される典型的なパターンは、テストしたいクラスと単体テスト コードを同じパッケージ (この場合はodp.proj) に配置しますが、異なるソース ツリーに配置することです。したがって、クラスを に入れ、src/odp/projテスト コードを に入れますtest/odp/proj。
Java には、何も指定されていない (つまり、public、private、または protected を指定していない) 場合のデフォルトのアクセス修飾子である「package」アクセス修飾子があります。「package」アクセス修飾子を使用すると、クラスのみodp.projがメソッドにアクセスできます。ただし、Java では、リフレクションを使用するとすべてのアクセスが可能になるため、アクセス規則を適用するためにアクセス修飾子に依存することはできないことに注意してください。アクセス修飾子は単なる示唆にすぎません (制限的なセキュリティ マネージャが存在しない限り)。
これは と の間の特別な関係ではありませんodp.proj-odp.proj.testそれらはたまたま関連しているように名前が付けられているだけです。
パッケージが単にテストを提供するだけの場合はodp.proj.test、同じパッケージ名 ( odp.proj) を使用できます。Eclipse や Netbeans などの IDEは、同じパッケージ名で JUnit セマンティクスを持つ別のフォルダー (src/main/java/odp/projおよび) を作成します。src/test/java/odp/proj
これらの IDE はメソッドのテストを生成しodp.proj、存在しないテスト メソッド用の適切なフォルダーを作成することに注意してください。
IntelliJ でこれを行うと、ソース ツリーは次のようになります。
src // source root
- odp
- proj // .java source here
- test // test root
- odp
- proj // JUnit or TestNG source here
他の人が説明したように、Java には「サブパッケージ」のようなものはありません。すべてのパッケージは分離されており、親から何も継承していません。
別のパッケージから保護されたクラス メンバーにアクセスする簡単な方法は、クラスを拡張してメンバーをオーバーライドすることです。
たとえばClassInA、 packageでアクセスするには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
}
}