前提
Windows11を使用しています
ディレクトリの指定は相対パスで行います
構成
例えば以下のディレクトリ構成を想定します
H:\Java
├─B
│  │
│  └─Y
│          Sub.java
│
├─C
│  │
│  └─Z
│          Base.java
│
└─A    
    │
    └─X
            Main.java            
それぞれのコードの実装は以下の通りです
package X;
import Y.Sub;
import Z.Base;
public class Main {
    public static void main(String[] args) {
        new Sub().Message();
        new Base().Run();
    }
}
package Y;
public class Sub {
    public void Message() {
        System.out.println("a");
    }
}
package Z;
import Y.Sub;
public class Base {
    public void Run() {
        System.out.println("b");
        new Sub().Message();
    }
}
コンパイル
これらのコードを実行するには、まずコンパイルによって.classファイルを作ります
クラスパスにはimport文にてパッケージ名として採用されたフォルダを含むフォルダをトップディレクトリとして指定します
H:\Java>javac A\X\Main.java -cp B;C
H:\Java>javac A\X\Main.java -cp B";"C
今回であればパッケージY,ZはフォルダB,Cに属するフォルダです
import Y.Sub;
import Z.Base;
import Y.Sub;
PowerShell(Windowsのみ?)上では複数のディレクトリを指定時に";"で区切る必要があります
ダブルクオーテーションで囲う必要があることに注意が必要です
javac javaファイル -cp クラスパス;クラスパス...
が、基本構文となります
ここまででディレクトリの状態は以下のようになりました
```:H:\Java
H:\Java
├─B
│  │
│  └─Y
│          Sub.java
│          Sub.class
│
├─C
│  │
│  └─Z
│          Base.java
│          Base.class
│
└─A    
    │
    └─X
            Main.java
            Main.class
実行
Javaコマンドを用いることでコードの実行が可能ですが、ファイルの指定方法には次の二つの種類があります
java -cp クラスパス;クラスパス... javaファイル
java -cp クラスパス;クラスパス... classファイル
ここで注意すべきなのがclassファイルを使用するケースです
まず、javaファイルの使用時は以下のように実行します
H:\Java>java -cp B;C A\X\Main.java
H:\Java>java -cp B";"C A\X\Main.java
a
b
a
実行対象のファイルを指定し、それぞれのパッケージのトップディレクトリを指定する直感的な方法です
では、クラスファイルの指定時はどうなるかというと、以下のような手続きになります
H:\Java>java -cp A;B;C X.Main
H:\Java>java -cp A";"B";"C X.Main
a
b
a
クラスファイルの使用時は、そのクラスファイルのソースコード内でpackageに指定されたフォルダを含むフォルダをトップディレクトリとしてクラスパスに含める必要があります
package X
という宣言がありました
つまりこのXというフォルダを含んだAをクラスパスに含めなければならないということです
A/X.Mainような書き方はできません
罠ですね
あとがき
クラスファイルを使用して実行する際に忘れがちなポイントなのでまとめました
嵌りどころだと思うのでディレクトリの指定時には常に意識しておきたいところです