假设我以某种方式从其他类获得了对象引用:
Object myObj = anObject;
现在我可以获得这个对象的类:
Class objClass = myObj.getClass();
现在,我可以获得该类的所有构造函数:
Constructor[] constructors = objClass.getConstructors();
现在,我可以循环每个构造函数:
if (constructors.length > 0)
{
for (int i = 0; i < constructors.length; i++)
{
System.out.println(constructors[i]);
}
}
这已经给了我一个关于构造函数的很好的总结,例如构造函数 public Test(String paramName) 显示为 public Test(java.lang.String)
然而,我不想给我类类型,而是想获取参数的名称..在本例中为“paramName”。我该怎么做呢?我尝试了以下操作但没有成功:
if (constructors.length > 0)
{
for (int iCon = 0; iCon < constructors.length; iCon++)
{
Class[] params = constructors[iCon].getParameterTypes();
if (params.length > 0)
{
for (int iPar = 0; iPar < params.length; iPar++)
{
Field fields[] = params[iPar].getDeclaredFields();
for (int iFields = 0; iFields < fields.length; iFields++)
{
String fieldName = fields[i].getName();
System.out.println(fieldName);
}
}
}
}
}
不幸的是,这并没有给我预期的结果。谁能告诉我我应该怎么做或者我做错了什么?谢谢!
正如评论中提到的罗曼的回答 https://stackoverflow.com/questions/2729580/how-to-get-the-parameter-names-of-an-objects-constructors-reflection/2729595#2729595, 参数名称can如果编译器包含调试符号,则可以检索,但不是通过标准 Java Reflection API。下面的示例说明了如何使用以下命令通过调试符号获取参数名称ASM字节码库 http://asm.ow2.org/:
/**
* Returns a list containing one parameter name for each argument accepted
* by the given constructor. If the class was compiled with debugging
* symbols, the parameter names will match those provided in the Java source
* code. Otherwise, a generic "arg" parameter name is generated ("arg0" for
* the first argument, "arg1" for the second...).
*
* This method relies on the constructor's class loader to locate the
* bytecode resource that defined its class.
*
* @param constructor
* @return
* @throws IOException
*/
public static List<String> getParameterNames(Constructor<?> constructor) throws IOException {
Class<?> declaringClass = constructor.getDeclaringClass();
ClassLoader declaringClassLoader = declaringClass.getClassLoader();
Type declaringType = Type.getType(declaringClass);
String constructorDescriptor = Type.getConstructorDescriptor(constructor);
String url = declaringType.getInternalName() + ".class";
InputStream classFileInputStream = declaringClassLoader.getResourceAsStream(url);
if (classFileInputStream == null) {
throw new IllegalArgumentException("The constructor's class loader cannot find the bytecode that defined the constructor's class (URL: " + url + ")");
}
ClassNode classNode;
try {
classNode = new ClassNode();
ClassReader classReader = new ClassReader(classFileInputStream);
classReader.accept(classNode, 0);
} finally {
classFileInputStream.close();
}
@SuppressWarnings("unchecked")
List<MethodNode> methods = classNode.methods;
for (MethodNode method : methods) {
if (method.name.equals("<init>") && method.desc.equals(constructorDescriptor)) {
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
List<String> parameterNames = new ArrayList<String>(argumentTypes.length);
@SuppressWarnings("unchecked")
List<LocalVariableNode> localVariables = method.localVariables;
for (int i = 0; i < argumentTypes.length; i++) {
// The first local variable actually represents the "this" object
parameterNames.add(localVariables.get(i + 1).name);
}
return parameterNames;
}
}
return null;
}
此示例使用 ASM 库的tree API http://asm.ow2.org/asm32/javadoc/user/org/objectweb/asm/tree/package-frame.html。如果速度和内存很宝贵,您可以重构示例以使用其访客API http://asm.ow2.org/asm32/javadoc/user/org/objectweb/asm/package-frame.html反而。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)