[Ljava.lang.String;@6d6f6e28 是什么意思

本文详细解析了Java中打印数组时出现的[LJava.lang.String;@hashcode现象,从System.out.println方法出发,逐步深入到Object类的toString方法及Class类的getName方法,解释了数组类型描述符的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题

打印 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 中的数据类型。

对于非数组类型:

类型类型描述符
booleanZ
byteB
charC
doubleD
floatF
intI
longJ
shortS
class or interfaceLclassname;

引用类型 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;"

至于为什么是 L,我猜是为了代表 class,但是 C 已经被 char 占了,只能取下一位的 L

参考链接:
https://stackoverflow.com/questions/5085889/l-array-notation-where-does-it-come-from

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值