JAVA类型描述符

JAVA类型描述符

在之前学习大佬们的文章时,在代码中看到”[D”,”[Ljava.lang.String;”等奇奇怪怪的符号,说是什么java类型描述符,所以记录总结一下类型描述符的学习过程

起因

在学习cobal1tstrike大佬的Java反射文章时,附上Java反射文件链接:Java代码审计基础 | Java反射 (qq.com)

其中有这么一段记录,如下:

可以看到上方代码中的”[D”,”[[Ljava.lang.String;”诸如此类奇奇怪怪的符号,仔细一看原来是数组类型描述符。

于是我写了个简单的打印字符串数组Demo:

1
2
3
4
5
6
7
8
package com.fanseTest;

public class shuzu_Demo1 {
public static void main(String[] args) {
String[] str1 = new String[]{"A","B","C"};
System.out.println(str1);
}
}

运行结果为:

分析

我们来看下打印字符串数组的过程;

1
2
3
4
5
6
7
8
9
10
11
12
13
// 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;@1540e19d是strs.toString()返回的值。strs的类型是String[],是一个数组类型,并且该数组类型没有重写toString()方法,我们来看下Object的toString方法:

1
2
3
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

@ 之后是 hashCode 的值,所以 [Ljava.lang.String; 就是 getClass().getName() 返回的值。即 strs.getClass().getName() == “[Ljava.lang.String;”。

我们在来看下Class的getName()方法:

1
2
3
4
5
6
public String getName() {
String name = this.name;
if (name == null)
this.name = name = getNameNative();
return name;
}

最终实现交给了getnamenative()方法。

类型描述符

在Class文件中,会通过类型描述符来 代表 java中的数据类型。

对于非数组类型:

引用类型Class的Classname,指的是它的Class文件二进制名。如java/lang/Thread.

对于数组类型;

即 [ + 自己元素类型的类型描述符,[的个数取决于数组的维度。

我们来看看getName()方法的文档:

  • 对于原始数据类型,返回其 java 关键字
  • 对于非数组引用类型,返回其 Java 标准二进制名
  • 对于数组引用类型,返回它类型描述符,并将其中的 \ 改为 .

前面 strs.getClass().getName(),strs 是一个数组类型,返回它的类型描述符。即 [ + 自己元素类型的类型描述符,它的元素类型是 String,String 类型的描述符是 Ljava/lang/String;,将其中的 / 改为 .,得到 Ljava.lang.String;。所以strs.getClass().getName() == “[Ljava.lang.String;”。

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信