转自https://www./5085889/ [L array notation - where does it come from? 我经常看到使用[L然后使用类型表示数组的消息,例如: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; (以上是我刚刚拔出的一个任意示例。)我知道这表示一个数组,但是语法从何而来? 为什么以[开头但没有右方括号? 为什么是L? 它纯粹是武断的,还是背后有其他历史/技术原因? 查看此帖子 对于读者来说,确实没有理由在邮件中使用这种格式。
[代表Array,Lsome.type.Here表示类型。这类似于Java虚拟机规范4.3中看到的字节码内部使用的类型描述符-尽可能简短。唯一的区别在于,实际描述符使用/而不是.表示包。 例如,对于基元,值是:对于int数组,其值为[I,而二维数组将为:[[I。 由于类可以有任何名称,因此很难识别它是什么类,因此L,类名以;结尾 描述符也用于表示字段和方法的类型。 例如: ...对应于参数为int,double和Thread且返回类型为Object的方法 编辑 您还可以使用Java Dissambler在.class文件中看到此内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| 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规范的字段描述
JVM数组描述符。 1 2 3 4 5 6 7 8 9
| [Z = boolean [B = byte [S = short [I = int [J = long [F = float [D = double [C = char [L = any non-primitives( Object) |
要获取主要数据类型,您需要: 1
| [ Object].getClass().getComponentType(); |
如果"对象"不是数组,它将返回null。 要确定它是否为数组,只需调用: 要么
在JNI(通常在内部是JVM)中使用它来指示类型。基元用单个字母表示(Z表示布尔值,I表示整数等),[表示数组,L用于类(以;终止)。 参见此处:JNI类型 编辑:详细说明为什么没有终止]-此代码是允许JNI / JVM快速识别方法及其签名。它旨在尽可能紧凑以使解析速度更快(=尽可能少的字符),因此[用于一个非常简单的数组(使用哪种更好的符号?)。对于int的I同样明显。
[L array notation - where does it come from?
来自JVM规范。这是在classFile格式和其他位置中指定的类型名称的表示。 是的,该符号也记录在其他地方。 Why?
毫无疑问,选择内部类型名称表示是因为它是: 但是尚不清楚他们为什么决定通过Class.getName()方法公开数组类型的内部类型名称。我认为他们可以将内部名称映射为更"人性化"的名称。我最大的猜测是,这只是他们直到太晚才解决的问题之一。 (没有人是完美的,甚至没有所谓的"智能设计师"。)
我认为这是因为C被char占用了,所以上课的下一个字母是L。
另一个来源是Class.getName()的文档。当然,所有这些规范都是一致的,因为它们相互适合。
|