Java classpathおよびリソースファイル読み込み

3806 ワード

デフォルトのclasspath
ORACLE documentation
The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, you must include "."in the new settings.
デフォルトのclasspathは、現在の作業ディレクトリである.です.環境変数CLASSPATHを設定するか、java-classpath(または-cp)パラメータを使用してこのデフォルト値を上書きします..からclasspathを含める場合は、.に追加して新しい設定に追加する必要があります.
java -cp .:/another/path:another/path2 package.class.to.run

一般に、グローバルなCLASSPATHに依存することなく、環境変数を修正したり、プログラムを他のコンピュータにコピーしたりして、プログラムの実行に影響を与えるやすい.
Class.getResource()とClassLoader.getResource()
使用
package path.classpath;
public class ClassPath {

    public static void main(String[] args) {
        System.out.println(System.getProperty("java.class.path"));
        System.out.println(ClassPath.class.getResource(""));
        System.out.println(ClassPath.class.getResource("/"));
        System.out.println(ClassPath.class.getClassLoader().getResource(""));
    }
}

実行:
java path.classpath.ClassPath

出力:
.
file:/home/smallfly/programming_projects/java/JavaLanguageFeatures/out/production/features/path/classpath/
file:/home/smallfly/programming_projects/java/JavaLanguageFeatures/out/production/features/
file:/home/smallfly/programming_projects/java/JavaLanguageFeatures/out/production/features/
null
Class.getResourceの2つの使い方が見られます.
  • 相対パス(/で始まる)を使用すると、ルートディレクトリがこのクラスのclassファイルが存在するディレクトリの下
  • に設定.
  • 絶対パス(/で始まる)を使用すると、ルートディレクトリがこのクラスのトップクラスpackageの下に設定.例えばA.classのパスがApp/classes/package1/package2/A.classであれば、フォローディレクトリはApp/classes/
  • に設定.ClassLoader.getResource使用法:
  • 相対パスとディレクトリは、トップレベルpackageの下
  • に設定.
  • 絶対パスはこの使い方をサポートせずnull
  • に直接戻ります.
    げんり
    ClassクラスのgetResourceメソッド:
        public java.net.URL getResource(String name) {
            name = resolveName(name);
            ClassLoader cl = getClassLoader0();
            if (cl==null) {
                // A system class.
                return ClassLoader.getSystemResource(name);
            }
            return cl.getResource(name);
        }
    
    nameパラメータを処理するresolveName方法:
    /**
    * Add a package name prefix if the name is not absolute Remove leading "/"
    * if name is absolute
    */
    private String resolveName(String name) {
            if (name == null) {
                return name;
            }
            if (!name.startsWith("/")) {
                Class> c = this;
                while (c.isArray()) {
                    c = c.getComponentType();
                }
                String baseName = c.getName();
                int index = baseName.lastIndexOf('.');
                if (index != -1) {
                    name = baseName.substring(0, index).replace('.', '/')
                        +"/"+name;
                }
            } else {
                name = name.substring(1);
            }
            return name;
        }
    

    実際にはClassクラスのgetResourceは、ClassLoadergetResourceメソッドを呼び出していることがわかります.resolveNameメソッドから、nameに対して以下の処理が行われていることがわかります.
  • ファイル名は/で始まる、すなわち、絶対パスは、先頭の/文字を除くサブ文字列
  • を直接返す.
  • ファイル名は相対経路でまず現在のクラスのクラス名(全限定名)を得る.配列タイプの処理に注意する.配列のクラス名はJavaの中では比較的奇妙であるため,そのwhileサイクルは配列の要素タイプを得るためである.その後,このクラスのpackageの中の.をディレクトリセパレータ/に置き換え,そして、受信したname.
  • をつなぐ.