Come ottenere i nomi dei parametri dei costruttori di un object (riflessione)?

Diciamo che in qualche modo ho ottenuto un riferimento a un object da un’altra class:

Object myObj = anObject; 

Ora posso ottenere la class di questo object:

 Class objClass = myObj.getClass(); 

Ora, posso ottenere tutti i costruttori di questa class:

 Constructor[] constructors = objClass.getConstructors(); 

Ora, posso eseguire il loop di ogni costruttore:

 if (constructors.length > 0) { for (int i = 0; i < constructors.length; i++) { System.out.println(constructors[i]); } } 

Questo mi sta già fornendo un buon riepilogo del costruttore, ad esempio un public constructor Test (String paramName) è mostrato come Test pubblico (java.lang.String)

Invece di darmi il tipo di class, voglio ottenere il nome del parametro .. in questo caso “paramName”. Come potrei farlo? Ho provato il seguente senza successo:

 if (constructors.length > 0) { for (int iCon = 0; iCon  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); } } } } } 

Sfortunatamente, questo non mi sta dando il risultato atteso. Qualcuno potrebbe dirmi come dovrei fare questo o quello che sto facendo male? Grazie!

Queste informazioni vengono perse dopo la compilazione e non possono essere recuperate in fase di runtime.

Come menzionato nei commenti sulla risposta di Roman , i nomi dei parametri possono essere recuperati se il compilatore include i simboli di debugging, sebbene non attraverso l’API Java Reflection standard. Di seguito è riportato un esempio che illustra come è ansible ottenere i nomi dei parametri tramite i simboli di debug utilizzando la libreria bytecode ASM :

 /** * 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 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 methods = classNode.methods; for (MethodNode method : methods) { if (method.name.equals("") && method.desc.equals(constructorDescriptor)) { Type[] argumentTypes = Type.getArgumentTypes(method.desc); List parameterNames = new ArrayList(argumentTypes.length); @SuppressWarnings("unchecked") List 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; } 

Questo esempio utilizza l' API dell'albero della libreria ASM. Se la velocità e la memoria sono preziose, puoi rifattorizzare l'esempio per utilizzare invece la sua API visitatore .

Prova https://github.com/paul-hammant/paranamer

Oh, per l’amor di Dio. In realtà, mi farai inserire almeno 30 caratteri per modificare una risposta esistente per correggerla.