Class.toString 问题

一定要细心 2019-12-05 05:17:19
1. 比如 JDK8 Boolean 中有一个常量叫

public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");

2. 那么在 TYPE.toString() 方法下

public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}

3. 会执行 getName() 本地方法,在本地方法定义中 JVM_GetClassName 名字

static JNINativeMethod methods[] = {
{"getName0", "()" STR, (void *)&JVM_GetClassName}
};

4. 那么网上很多博客都千篇一律都说:

原文摘取:getName0根据一个数组获得对应的名称,JVM根据Java层的Class可得到对应类型的数组下标,比如这里下标为4,则名称为”boolean”。

const char* type2name_tab[T_CONFLICT+1] = {
NULL, NULL, NULL, NULL,
"boolean",
"char",
"float",
"double",
"byte",
"short",
"int",
"long",
"object",
"array",
"void",
"*address*",
"*narrowoop*",
"*conflict*"
};

疑惑:到底是怎么找到这个数组的???
...全文
96 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
一定要细心 2019-12-05
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
这个数组不是在java定义的,是在jvm的c源代码里定义的
java通过jni的调用c的代码,在c代码里有个对应JVM_GetClassName的方法,JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))
里面就行代码 name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls)));
这里就会用到你说的这个数组
参考源码
https://github.com/mercyblitz/segmentfault-lessons/tree/master/「一入%20Java%20深似海%20」/第五期/第一节%20Java%20类的层次

java调用jni的方法定一个在一个数组里,这个数组是一个结构体,里面有jni方法名和c源码的函数地址(也就是一个函数指针类型)
static JNINativeMethod methods[] = {
{"getName0", "()" STR, (void *)&JVM_GetClassName},
{"getSuperclass", "()" CLS, NULL},
{"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
{"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
{"isInterface", "()Z", (void *)&JVM_IsInterface},
{"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
{"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners},
{"isArray", "()Z", (void *)&JVM_IsArrayClass},
{"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass},
{"getComponentType", "()" CLS, (void *)&JVM_GetComponentType},
{"getModifiers", "()I", (void *)&JVM_GetClassModifiers},
{"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields},
{"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods},
{"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
{"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
{"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
{"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
{"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo},
{"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
};
所以java层次调用getName0,c底层就调用JVM_GetClassName,JVM_GetClassName方法里就会用到你说的那个数组

感谢
qybao 2019-12-05
  • 打赏
  • 举报
回复
这个数组不是在java定义的,是在jvm的c源代码里定义的
java通过jni的调用c的代码,在c代码里有个对应JVM_GetClassName的方法,JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))
里面就行代码 name = type2name(java_lang_Class::primitive_type(JNIHandles::resolve(cls)));
这里就会用到你说的这个数组
参考源码
https://github.com/mercyblitz/segmentfault-lessons/tree/master/「一入%20Java%20深似海%20」/第五期/第一节%20Java%20类的层次

java调用jni的方法定一个在一个数组里,这个数组是一个结构体,里面有jni方法名和c源码的函数地址(也就是一个函数指针类型)
static JNINativeMethod methods[] = {
{"getName0", "()" STR, (void *)&JVM_GetClassName},
{"getSuperclass", "()" CLS, NULL},
{"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces},
{"getClassLoader0", "()" JCL, (void *)&JVM_GetClassLoader},
{"isInterface", "()Z", (void *)&JVM_IsInterface},
{"getSigners", "()[" OBJ, (void *)&JVM_GetClassSigners},
{"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners},
{"isArray", "()Z", (void *)&JVM_IsArrayClass},
{"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass},
{"getComponentType", "()" CLS, (void *)&JVM_GetComponentType},
{"getModifiers", "()I", (void *)&JVM_GetClassModifiers},
{"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields},
{"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods},
{"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
{"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
{"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
{"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
{"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo},
{"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations},
};
所以java层次调用getName0,c底层就调用JVM_GetClassName,JVM_GetClassName方法里就会用到你说的那个数组

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧