[L 数组表示法 - 它来自哪里?
我经常看到使用类型来表示数组的消息,例如:[L
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
(以上是我刚刚拉出来的任意例子。我知道这表示数组,但是语法来自哪里?为什么开头却没有右方括号?为什么是L?这纯粹是武断的,还是背后还有其他历史/技术原因?[
我经常看到使用类型来表示数组的消息,例如:[L
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
(以上是我刚刚拉出来的任意例子。我知道这表示数组,但是语法来自哪里?为什么开头却没有右方括号?为什么是L?这纯粹是武断的,还是背后还有其他历史/技术原因?[
[
代表数组,表示类型。这类似于 Java 虚拟机规范的 §4.3 中的字节码内部使用的类型描述符 - 选择尽可能简短。唯一的区别在于真正的描述符使用而不是表示包。Lsome.type.Here
/
.
例如,对于基元,值为:对于 int 数组,二维数组将为:。[I
[[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 规范上的字段描述
JVM 数组描述符。
[Z = boolean
[B = byte
[S = short
[I = int
[J = long
[F = float
[D = double
[C = char
[L = any non-primitives(Object)
要获取主数据类型,您需要:
[Object].getClass().getComponentType();
如果“对象”不是数组,它将返回 null。要确定它是否是数组,只需调用:
[Any Object].getClass().isArray()
或
Class.class.isArray();