一、问题
打印 String[]
String[] strs = new String[]{"a", "b", "c"};
System.out.println(strs);
输出
[Ljava.lang.String;@6d6f6e28
java.lang.String;、@6d6f6e28 我都能理解,[L 是什么意思呢?
二、初探
看一下 System.out.println(strs) 的过程:
// PrintStream.java
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
// String.java
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
可以看出,[Ljava.lang.String;@6d6f6e28 就是 strs.toString() 返回的值。
strs 的类型是 String[],是一个数组类型,数组类型没有重写 toString 方法,所以看下 Object 的 toString 方法:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
@ 之后是 hashCode 的值,所以 [Ljava.lang.String; 就是 getClass().getName() 返回的值。即 strs.getClass().getName() == "[Ljava.lang.String;"。
三、深入
再看下 Class 的 getName() 方法:
public String getName() {
String name = this.name;
if (name == null)
this.name = name = getNameNative();
return name;
}
最终实现交给了 getNameNative() 方法,这是一个 native 方法,看不到源码,但 getName() 方法前的文档注释已经很清楚了。(太长,下面会有文档链接)
在看 getName() 方法的文档前,还要先看一下 class 文件中的 java 类型表示:
在 class 文件中,会通过类型描述符(即字段描述符)来代表 java 中的数据类型。
对于非数组类型:
| 类型 | 类型描述符 |
|---|---|
| boolean | Z |
| byte | B |
| char | C |
| double | D |
| float | F |
| int | I |
| long | J |
| short | S |
| class or interface | Lclassname; |
引用类型 class 的 classname,指的是它的 class 文件二进制名(即全限定名,更多见二进制名与全限定名),如 java/lang/Thread。
对于数组类型:
| 类型 | 类型描述符 |
|---|---|
| boolean[] | [Z |
| boolean[][] | [[Z |
| byte[] | [B |
| byte[][] | [[B |
| char[] | [C |
| char[][] | [[C |
| … | … |
| class or interface[] | [Lclassname; |
| class or interface[][] | [[Lclassname; |
即 [ + 自己元素类型的类型描述符,[ 的个数取决于数组的维度。
现在再来看 getName() 方法的文档,翻译总结如下:
- 对于原始数据类型,返回其 java 关键字
- 对于非数组引用类型,返回其 Java 标准二进制名
- 对于数组引用类型,返回它类型描述符,并将其中的
\改为.
再回到最初的 strs.getClass().getName(),strs 是一个数组类型,返回它的类型描述符,即 [ + 自己元素类型的类型描述符,它的元素类型是 String,String 类型的描述符是 Ljava/lang/String;,将其中的 / 改为 .,得到 Ljava.lang.String;。所以strs.getClass().getName() == "[Ljava.lang.String;"。
参考链接:
https://stackoverflow.com/questions/5085889/l-array-notation-where-does-it-come-from