我经常看到使用[L然后使用类型来表示数组的消息,例如:
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
(以上是我刚刚拔出的任意示例。)我知道这表示一个数组,但是语法从何而来?为什么以[开头但没有方括号呢?为什么是L?它纯粹是武断的,还是背后有其他历史/技术原因?

最佳答案

[代表Array,Lsome.type.Here表示类型。这类似于在§4.3 of the Java Virtual Machine Specification中看到的字节码内部使用的的类型描述符-选择为尽可能简短。唯一的区别在于,实际描述符使用/而不是.表示包。

例如,对于基元,值是:int数组的[I,二维数组将是:[[I

由于类可以有任何名称,因此很难识别它是什么类,因此L,类名以;结尾

描述符也用于表示字段和方法的类型。

例如:

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

...对应于参数为intdoubleThread的方法,返回类型为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行):

引用:Field description on the JVM specification

07-24 09:45
查看更多