文章来源于:javatpoint
package java8_demo;
public class Calculate {
int add(int a, int b){
return (a+b);
}
int mul(int a, int b){
return (b*a);
}
}
package java8_demo;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class ParameterReflection {
public static void main(String[] args) {
// Creating object of a class
Calculate calculate = new Calculate();
// instantiating Class class
Class cls = calculate.getClass();
// Getting declared methods inside the Calculate class
Method[] method = cls.getDeclaredMethods(); // It returns array of methods
// Iterating method array
for (Method method2 : method) {
System.out.print(method2.getName()); // getting name of method
// Getting parameters of each method
Parameter parameter[] = method2.getParameters(); // It returns array of parameters
// Iterating parameter array
for (Parameter parameter2 : parameter) {
System.out.print(" "+parameter2.getParameterizedType()); // returns type of parameter
System.out.print(" "+parameter2.getName()); // returns parameter name
}
System.out.println();
}
}
}
使用-parameters
-parameter flag in the above command is used to store parameters in the Calculate class file. By default .class does not store parameters and returns argsN as parameter name, where N is a number of parameters in the method.
使用下面命令执行Calculate.java之后,然后反编译
src/main/java/java8_demo$ javac -parameters Calculate.java
反编译后的代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package java8_demo;
public class Calculate {
public Calculate() {
}
int add(int a, int b) {
return var1 + var2;
}
int mul(int a, int b) {
return var2 * var1;
}
}
最后执行:
main/java/java8_demo$ javac -cp ../ ParameterReflection.java
main/java/java8_demo$ java -cp ../ java8_demo.ParameterReflection
mul int a int b
add int a int b
不使用-parameters
main/java/java8_demo$ javac Calculate.java
main/java/java8_demo$ java -cp ../ java8_demo.ParameterReflection
mul int arg0 int arg1
add int arg0 int arg1
反编译后的代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package java8_demo;
public class Calculate {
public Calculate() {
}
int add(int var1, int var2) {
return var1 + var2;
}
int mul(int var1, int var2) {
return var2 * var1;
}
}
How to Access Parameter Names
Java 8 provides java.lang.reflect.Parameter
class that will give information about parameters name and its modifiers. Before java 8 we cannot directly get the parameters name of a method or constructor. Spring and other framework uses parameter level annotation to get method parameter name. Here on this page we will provide -parameters
configuration in maven, gradle and eclipse. To get parameter names javac
must use -parameters
as javac -parameters
.
Scenario 1- Using Java 8 Reflection API
Using Java 8 Reflection API, we need to follow two steps.
a. Compile source code using javac -parameter
.
b. Use Parameter
class to access method and constructor parameters using its methods such as isNamePresent()
and getName()
.
isNamePresent()
checks if .class
contains original parameter names as in source code or not. If we have not used -parameters
compiler argument, it will return false otherwise true.
getName()
returns the parameter names. If -parameters
compiler argument has not been used, getName()
method will return parameter name as arg0, arg1 etc.
Scenario 2- Before Java 8 without using Parameter class.
Frameworks like spring uses annotation to get parameter name. Parameters are annotated with the value as parameter name. Find the code snippet.
public String info(@RequestParam(value="key") String key) {
}
Using reflection API, the annotation value is accessed.
Java 8 “-parameters” Compiler Argument
To get the method and constructor parameter names, it is necessary that class must be compiled using -parameters
compiler argument. With this compilation .class
file keeps method and constructor parameter as defined in source code. If we does not use -parameters
compiler argument, after compilation .class
file does not keeps original parameters name as in source code and it is renamed as arg0, arg1 etc. To get parameter names javac
must use -parameters
as follows
javac -parameters
Set “-parameters” Compiler Argument in Eclipse
To set -parameters
compiler argument in ellipse follow the below steps.
- Go to Window-> Preferences-> Java-> Compiler
- Select Store information about method parameters (usable via reflection) and click ok. This is equivalent to javac -parameters command.
Find the print screen.
Gradle using “-parameters” Compiler Argument
Find the gradle file to use -parameters
compiler argument.
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
archivesBaseName = 'Concretepage'
version = '1.0-SNAPSHOT'
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters"
}
}
repositories {
mavenCentral()
}
dependencies {
}
Maven using “-parameters” Compiler Argument
Find the maven file to use -parameters
compiler argument.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.concretepage.app</groupId>
<artifactId>commonapp</artifactId>
<version> 1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java App with Maven</name>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Access Method Parameters using Java 8 Reflection
Find the example to access method parameters name using java 8 reflection API.
MethodParameterNamesDemo.java
package com.concretepage;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class MethodParameterNamesDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Method[] methods = BookService.class.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
System.out.println("-------------");
Parameter[] parameters = method.getParameters();
for (Parameter p : parameters) {
if (p.isNamePresent()) {
System.out.println(p.getName());
}
}
}
}
}
BookService.java
package com.concretepage;
public class BookService {
public BookService(Integer bookId, String bookDesc) {
System.out.println(bookId +":"+ bookDesc );
}
public void evaluateBook(String bookName, Integer bookPrice) {
System.out.println(bookName + ":" + bookPrice);
}
}
Find the output.
evaluateBook
-------------
bookName
bookPrice
Access Constructor Parameters using Java 8 Reflection
Find the example to access constructor parameters name using java 8 reflection API.
ConstructorParameterNamesDemo.java
package com.concretepage;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
public class ConstructorParameterNamesDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Constructor<?>[] constructors = BookService.class.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.getName());
System.out.println("-------------");
Parameter[] parameters = constructor.getParameters();
for (Parameter p : parameters) {
if (p.isNamePresent()) {
System.out.println(p.getName());
}
}
}
}
}
Find the output.
com.concretepage.BookService
-------------
bookId
bookDesc
参考文章:
1、https://blog.csdn.net/alex_xfboy/article/details/89643340
2、https://www.concretepage.com/java/jdk-8/java-8-reflection-access-to-parameter-names-of-method-and-constructor-with-maven-gradle-and-eclipse-using-parameters-compiler-argument