7

Class.forName()がClassNotFoundExceptionをスローする場合と、NoClassDefFoundErrorをスローする場合について、プラットフォーム間で違いが見られます。この動作はどこかで明確に定義されていますか、それともバグに遭遇しましたか?

次のコード(デフォルトパッケージのスタンドアロンJavaファイル)について考えてみます。

public class DLExceptionType {

  private static void printFindError(String name) {
    System.out.print(name + ": ");
    try {
      Class.forName(name);
      System.out.println("** no error **");
    } catch (Throwable e) {
      System.out.println(e);
    }
  }

  public static void main(String[] args) {
    printFindError("DLExceptionType");
    printFindError("dLExceptionType"); // note the mis-capitalization
  }
}

このコードは、Linuxで期待される出力を生成します。

[eos18:~]$ java -version DLExceptionType
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
[eos18:~]$ java DLExceptionType
DLExceptionType: ** no error **
dLExceptionType: java.lang.ClassNotFoundException: dLExceptionType

これは、Windowsで異なるが理解できる出力を生成します。

java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) Client VM (build 21.1-b02, mixed mode, sharing)

Y:\Temp>java DLExceptionType
DLExceptionType: ** no error **
dLExceptionType: java.lang.NoClassDefFoundError: dLExceptionType (wrong name:  DLExceptionType)

Windowsでの出力は理にかなっています。ファイルシステムでは大文字と小文字が区別されないため、JVMはファイルdLExceptionType.classをロードしますが、そのファイルには別の名前のクラスが含まれています:DLExceptionType

ただし、Macでコードを実行すると(大文字と小文字が区別されるファイルシステムとLinuxボックスよりも新しいJVMがあります)、Windowsと同じ出力が得られます。

$ java -version
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
$ java DLExceptionType
DLExceptionType: ** no error **
dLExceptionType: java.lang.NoClassDefFoundError: dLExceptionType (wrong name: DLExceptionType)
4

2 に答える 2

3

HFS +(Mac Extended)は通常、大文字と小文字を区別しません。Mac OS 10.3以降、Appleは大文字と小文字を区別できるHFSXを導入しました(ただし、デフォルトではありません)。ディスクの初期化でオプションを指定しなかった場合、ボリュームでは大文字と小文字が区別されない可能性があります。

参照: http: //en.wikipedia.org/wiki/HFS_Plus

于 2011-11-12T14:47:58.440 に答える
0

ここにバグはありません。表示されているのは、ファイルシステムの大文字と小文字の区別が完全に原因です。

dLExceptionType大文字と小文字を区別しないファイルシステムにクラスをロードすると、JVMはファイルを見つけることができますdLException.class。ただし、含まれているクラスには名前がないため、がdLException発生しNoClassDefFoundErrorます。大文字と小文字を区別するファイルシステムにこのクラスをロードしようとすると、JVMはファイルをまったく見つけることができません。

メッセージ内のNoClassDefFoundErrorwith(wrong name: ...)は、読み取られたファイル名とは異なる名前を持つように見えるクラスをロードするたびに、JVMによってスローされます。クラスファイルの名前を変更して実行を試みることにより、任意のファイルシステムでこれを試すことができます。

于 2011-11-12T16:39:12.667 に答える