1. ホーム
  2. java

[解決済み] [L配列表記 - その由来は?

2023-06-02 12:56:26

質問

というメッセージはよく見かけますが [L を使っているメッセージをよく見かけますが、これは配列を表す型です。

[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

(上記は私が勝手に引いた例です。) これが配列を意味することはわかりますが、この構文はどこから来ているのでしょうか?なぜ、冒頭の [ と書いてあるのに、閉じ角括弧がないのはなぜか?また、なぜLなのでしょうか?純粋に恣意的なのか、それとも何か他の歴史的/技術的な理由があるのでしょうか?

どのように解決するのですか?

[ はArrayを表し Lsome.type.Here は型を意味します。これは型記述子が使われるのと似ている バイトコードで内部的に使われる で見られる Java仮想マシン仕様の§4.3 -- にあります。 なるべく簡潔に . 唯一の違いは リアル ディスクリプタは / よりも . ではなく、パッケージを表すために

例えば、プリミティブの場合、その値は [I intの配列の場合、2次元の配列は次のようになります。 [[I .

クラスは任意の名前を持つことができるので、それがどのクラスであるかを識別することが難しくなります。 L で終わる場合、クラス名は ;

ディスクリプタは、フィールドやメソッドの種類を表すためにも使われます。

例えば

(IDLjava/lang/Thread;)Ljava/lang/Object;

... はメソッドに対応し、そのパラメータは int , double そして Thread で、戻り値の型は Object

編集

java dissambler を使って、.class ファイルで見ることもできます。

C:>more > S.java
class S {
  Object  hello(int i, double d, long j, Thread t ) {
   return new Object();
  }
}
^C
C:>javac S.java

C:>javap -verbose S
class S extends java.lang.Object
  SourceFile: "S.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #2.#12; //  java/lang/Object."<init>":()V
const #2 = class        #13;    //  java/lang/Object
const #3 = class        #14;    //  S
const #4 = Asciz        <init>;
const #5 = Asciz        ()V;
const #6 = Asciz        Code;
const #7 = Asciz        LineNumberTable;
const #8 = Asciz        hello;
const #9 = Asciz        (IDJLjava/lang/Thread;)Ljava/lang/Object;;
const #10 = Asciz       SourceFile;
const #11 = Asciz       S.java;
const #12 = NameAndType #4:#5;//  "<init>":()V
const #13 = Asciz       java/lang/Object;
const #14 = Asciz       S;

{
S();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
  LineNumberTable:
   line 1: 0


java.lang.Object hello(int, double, long, java.lang.Thread);
  Code:
   Stack=2, Locals=7, Args_size=5
   0:   new     #2; //class java/lang/Object
   3:   dup
   4:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   7:   areturn
  LineNumberTable:
   line 3: 0


}

そして、生のクラスファイル(5行目を見てください)。

参照 JVMの仕様に関するフィールドの説明