mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
!644 新增ReflectUtil.getDescriptor获取单个class的描述符重载,完善测试用例和注释信息
Merge pull request !644 from 阿超/v6-dev
This commit is contained in:
commit
a7dcd4ce98
@ -33,7 +33,8 @@ public class ReflectUtil {
|
|||||||
*
|
*
|
||||||
* @param executable 可执行的反射对象
|
* @param executable 可执行的反射对象
|
||||||
* @return 描述符
|
* @return 描述符
|
||||||
* 参考:<a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">jvm定义的Field Descriptors(字段描述)</a>
|
* @link <a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">jvm定义的Field Descriptors(字段描述)</a>
|
||||||
|
* @link <a href="https://public static class.gitee.io/2022/06/07/%E7%B1%BB%E5%9E%8B%E6%8F%8F%E8%BF%B0%E7%AC%A6/">关于类型描述符的博客</a>
|
||||||
* <p>例:</p>
|
* <p>例:</p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code ReflectUtil.getDescriptor(Object.class.getMethod("hashCode")) // "()I"}</li>
|
* <li>{@code ReflectUtil.getDescriptor(Object.class.getMethod("hashCode")) // "()I"}</li>
|
||||||
@ -42,21 +43,18 @@ public class ReflectUtil {
|
|||||||
* <li>{@code ReflectUtil.getDescriptor(ReflectUtil.class.getDeclaredMethod("appendDescriptor", Class.clas, StringBuilder.class)) // "(Ljava/lang/Class;Ljava/lang/StringBuilder;)V"}</li>
|
* <li>{@code ReflectUtil.getDescriptor(ReflectUtil.class.getDeclaredMethod("appendDescriptor", Class.clas, StringBuilder.class)) // "(Ljava/lang/Class;Ljava/lang/StringBuilder;)V"}</li>
|
||||||
* <li>{@code ReflectUtil.getDescriptor(ArrayUtil.class.getMethod("isEmpty", Object[].class)) // "([Ljava/lang/Object;)Z"}</li>
|
* <li>{@code ReflectUtil.getDescriptor(ArrayUtil.class.getMethod("isEmpty", Object[].class)) // "([Ljava/lang/Object;)Z"}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
* @author VampireAchao
|
||||||
* Object.class.getMethod("hashCode")
|
|
||||||
*/
|
*/
|
||||||
public static String getDescriptor(Executable executable) {
|
public static String getDescriptor(Executable executable) {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
stringBuilder.append('(');
|
stringBuilder.append('(');
|
||||||
Class<?>[] parameters = executable.getParameterTypes();
|
Class<?>[] parameters = executable.getParameterTypes();
|
||||||
for (Class<?> parameter : parameters) {
|
for (Class<?> parameter : parameters) {
|
||||||
appendDescriptor(parameter, stringBuilder);
|
stringBuilder.append(getDescriptor(parameter));
|
||||||
}
|
}
|
||||||
if (executable instanceof Method) {
|
if (executable instanceof Method) {
|
||||||
Method method = (Method) executable;
|
Method method = (Method) executable;
|
||||||
stringBuilder.append(')');
|
return stringBuilder.append(')').append(getDescriptor(method.getReturnType())).toString();
|
||||||
appendDescriptor(method.getReturnType(), stringBuilder);
|
|
||||||
return stringBuilder.toString();
|
|
||||||
} else if (executable instanceof Constructor) {
|
} else if (executable instanceof Constructor) {
|
||||||
return stringBuilder.append(")V").toString();
|
return stringBuilder.append(")V").toString();
|
||||||
}
|
}
|
||||||
@ -64,65 +62,63 @@ public class ReflectUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接描述符
|
* 获取类型描述符,这是编译成class文件后的二进制名称
|
||||||
*
|
*
|
||||||
* @param clazz 类
|
* @param clazz 类
|
||||||
* @param stringBuilder 描述符
|
|
||||||
* @link <a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">jvm定义的Field Descriptors(字段描述)</a>
|
* @link <a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">jvm定义的Field Descriptors(字段描述)</a>
|
||||||
|
* @link <a href="https://public static class.gitee.io/2022/06/07/%E7%B1%BB%E5%9E%8B%E6%8F%8F%E8%BF%B0%E7%AC%A6/">关于类型描述符的博客</a>
|
||||||
|
* <p>例:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code ReflectUtil.getDescriptor(boolean.class) "Z"}</li>
|
||||||
|
* <li>{@code ReflectUtil.getDescriptor(Boolean.class) "Ljava/lang/Boolean;"}</li>
|
||||||
|
* <li>{@code ReflectUtil.getDescriptor(double[][][].class) "[[[D"}</li>
|
||||||
|
* <li>{@code ReflectUtil.getDescriptor(int.class) "I"}</li>
|
||||||
|
* <li>{@code ReflectUtil.getDescriptor(Integer.class) "Ljava/lang/Integer;"}</li>
|
||||||
|
* </ul>
|
||||||
|
* @author VampireAchao
|
||||||
*/
|
*/
|
||||||
private static void appendDescriptor(Class<?> clazz, StringBuilder stringBuilder) {
|
public static String getDescriptor(Class<?> clazz) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
Class<?> currentClass;
|
Class<?> currentClass;
|
||||||
for (currentClass = clazz;
|
for (currentClass = clazz;
|
||||||
currentClass.isArray();
|
currentClass.isArray();
|
||||||
currentClass = currentClass.getComponentType()) {
|
currentClass = currentClass.getComponentType()) {
|
||||||
|
// 如果当前是数组描述符
|
||||||
stringBuilder.append('[');
|
stringBuilder.append('[');
|
||||||
}
|
}
|
||||||
if (currentClass.isPrimitive()) {
|
if (currentClass.isPrimitive()) {
|
||||||
stringBuilder.append(getDescriptorChar(currentClass));
|
// 只有下面九种基础数据类型以及数组,才有独立的描述符
|
||||||
} else {
|
final char descriptor;
|
||||||
stringBuilder.append('L').append(currentClass.getName().replace('.', '/')).append(';');
|
// see sun.invoke.util.Wrapper
|
||||||
}
|
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取单个描述符
|
|
||||||
*
|
|
||||||
* @param currentClass 当前类
|
|
||||||
* @return 描述符
|
|
||||||
*/
|
|
||||||
private static char getDescriptorChar(Class<?> currentClass) {
|
|
||||||
if (currentClass == boolean.class) {
|
if (currentClass == boolean.class) {
|
||||||
return 'Z';
|
descriptor = 'Z';
|
||||||
}
|
} else if (currentClass == byte.class) {
|
||||||
if ( currentClass == byte.class) {
|
descriptor = 'B';
|
||||||
return 'B';
|
} else if (currentClass == short.class) {
|
||||||
}
|
descriptor = 'S';
|
||||||
if (currentClass == short.class) {
|
} else if (currentClass == char.class) {
|
||||||
return 'S';
|
descriptor = 'C';
|
||||||
}
|
} else if (currentClass == int.class) {
|
||||||
if (currentClass == char.class) {
|
descriptor = 'I';
|
||||||
return 'C';
|
} else if (currentClass == long.class) {
|
||||||
}
|
descriptor = 'J';
|
||||||
if (currentClass == int.class) {
|
} else if (currentClass == float.class) {
|
||||||
return 'I';
|
descriptor = 'F';
|
||||||
}
|
} else if (currentClass == double.class) {
|
||||||
if (currentClass == long.class) {
|
descriptor = 'D';
|
||||||
return 'J';
|
} else if (currentClass == void.class) {
|
||||||
}
|
// VOID must be the last type, since it is "assignable" from any other type:
|
||||||
if (currentClass == float.class) {
|
descriptor = 'V';
|
||||||
return 'F';
|
} else {
|
||||||
}
|
|
||||||
if (currentClass == double.class) {
|
|
||||||
return 'D';
|
|
||||||
}
|
|
||||||
if (currentClass == Object.class) {
|
|
||||||
return 'L';
|
|
||||||
}
|
|
||||||
if (currentClass == void.class) {
|
|
||||||
return 'V';
|
|
||||||
}
|
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
stringBuilder.append(descriptor);
|
||||||
|
} else {
|
||||||
|
// 否则一律是 "L"+类名.replace('.', '/')+";"格式的对象类型
|
||||||
|
stringBuilder.append('L').append(currentClass.getName().replace('.', '/')).append(';');
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package cn.hutool.core.reflect;
|
package cn.hutool.core.reflect;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反射工具类单元测试
|
* 反射工具类单元测试
|
||||||
*
|
*
|
||||||
@ -113,10 +115,21 @@ public class ReflectUtilTest {
|
|||||||
@Test
|
@Test
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void testGetDescriptor() {
|
public void testGetDescriptor() {
|
||||||
|
// methods
|
||||||
Assert.equals("()I", ReflectUtil.getDescriptor(Object.class.getMethod("hashCode")));
|
Assert.equals("()I", ReflectUtil.getDescriptor(Object.class.getMethod("hashCode")));
|
||||||
Assert.equals("()Ljava/lang/String;", ReflectUtil.getDescriptor(Object.class.getMethod("toString")));
|
Assert.equals("()Ljava/lang/String;", ReflectUtil.getDescriptor(Object.class.getMethod("toString")));
|
||||||
Assert.equals("(Ljava/lang/Object;)Z", ReflectUtil.getDescriptor(Object.class.getMethod("equals", Object.class)));
|
Assert.equals("(Ljava/lang/Object;)Z", ReflectUtil.getDescriptor(Object.class.getMethod("equals", Object.class)));
|
||||||
Assert.equals("(Ljava/lang/Class;Ljava/lang/StringBuilder;)V", ReflectUtil.getDescriptor(ReflectUtil.class.getDeclaredMethod("appendDescriptor", Class.class, StringBuilder.class)));
|
Assert.equals("(II)I", ReflectUtil.getDescriptor(Integer.class.getDeclaredMethod("compare", int.class, int.class)));
|
||||||
Assert.equals("([Ljava/lang/Object;)Z", ReflectUtil.getDescriptor(ArrayUtil.class.getMethod("isEmpty", Object[].class)));
|
Assert.equals("([Ljava/lang/Object;)Ljava/util/List;", ReflectUtil.getDescriptor(Arrays.class.getMethod("asList", Object[].class)));
|
||||||
|
Assert.equals("()V", ReflectUtil.getDescriptor(Object.class.getConstructor()));
|
||||||
|
// clazz
|
||||||
|
Assert.equals("Z", ReflectUtil.getDescriptor(boolean.class));
|
||||||
|
Assert.equals("Ljava/lang/Boolean;", ReflectUtil.getDescriptor(Boolean.class));
|
||||||
|
Assert.equals("[[[D", ReflectUtil.getDescriptor(double[][][].class));
|
||||||
|
Assert.equals("I", ReflectUtil.getDescriptor(int.class));
|
||||||
|
Assert.equals("Ljava/lang/Integer;", ReflectUtil.getDescriptor(Integer.class));
|
||||||
|
Assert.equals("V", ReflectUtil.getDescriptor(void.class));
|
||||||
|
Assert.equals("Ljava/lang/Void;", ReflectUtil.getDescriptor(Void.class));
|
||||||
|
Assert.equals("Ljava/lang/Object;", ReflectUtil.getDescriptor(Object.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user