Как сказал @Bozho, это возможно, если во время компиляции включена отладочная информация. Здесь есть хороший ответ ...
Как получить имена параметров конструкторов объекта (отражение)? by @AdamPaynter
... используя библиотеку ASM. Я собрал пример, показывающий, как вы можете достичь своей цели.
Прежде всего, начните с pom.xml с этими зависимостями.
org.ow2.asm
asm-all
5.2
junit
junit
4.12
test
Затем этот класс должен делать что ты хочешь. Просто вызовите статический метод getParameterNames()
.
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodNode;
public class ArgumentReflection {
/**
* 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 theMethod
* @return
* @throws IOException
*/
public static List getParameterNames(Method theMethod) throws IOException {
Class> declaringClass = theMethod.getDeclaringClass();
ClassLoader declaringClassLoader = declaringClass.getClassLoader();
Type declaringType = Type.getType(declaringClass);
String constructorDescriptor = Type.getMethodDescriptor(theMethod);
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(theMethod.getName()) && 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 = 1; i <= argumentTypes.length; i++) {
// The first local variable actually represents the "this"
// object if the method is not static!
parameterNames.add(localVariables.get(i).name);
}
return parameterNames;
}
}
return null;
}
}
Вот пример с модульным тестом.
public class ArgumentReflectionTest {
@Test
public void shouldExtractTheNamesOfTheParameters3() throws NoSuchMethodException, SecurityException, IOException {
List parameterNames = ArgumentReflection
.getParameterNames(Clazz.class.getMethod("callMe", String.class, String.class));
assertEquals("firstName", parameterNames.get(0));
assertEquals("lastName", parameterNames.get(1));
assertEquals(2, parameterNames.size());
}
public static final class Clazz {
public void callMe(String firstName, String lastName) {
}
}
}
Вы можете найти полный пример в GitHub
static
. Это связано с тем, что количество аргументов, возвращаемых ASM, различно, но это то, что можно легко устранить. Это было проблемой с другими таблицами начальной загрузки в прошлом. Добавление style="width: 33.3333%"
, кажется, делает трюк при добавлении к каждому тегу <th>
. Он стандартизирует ширину столбцов таблицы.
Используйте этот ресурс, чтобы ответить на другие ваши вопросы: Как настроить фиксированную ширину для < td >?
<div class="row pt-2 pb-4">
<table class="table pb-5">
<thead class="border-0">
<tr>
<th style="width: 33.3333%" class="border-top-none typeface-montserrat-500" scope="col">Content here with text</th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td>Content here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
</tbody>
</table>
</div>
<div class="row pt-2 pb-4">
<table class="table pb-5">
<thead class="border-0">
<tr>
<th style="width: 33.3333%" class="border-top-none typeface-montserrat-500" scope="col">Content here with text</th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td>Content here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content with more text here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content with more text here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
</tbody>
</table>
</div>
<div class="row pt-2 pb-4">
<table class="table pb-5">
<thead class="border-0">
<tr>
<th style="width: 33.3333%" class="border-top-none typeface-montserrat-500" scope="col">Content here with some different text again</th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
<th style="width: 33.3333%" class="border-top-none" scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td>Content here</td>
<td class="color-grey-dark">Content here once more</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content with more text here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content with more text here</td>
<td class="color-grey-dark">Content here with even more text</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
<tr>
<td>Content here</td>
<td class="color-grey-dark">Content here</td>
<td><a href="" class="btn btn-blue-light float-right px-4 py-1">Content here</a></td>
</tr>
</tbody>
</table>
</div>