Method Parameter Reflection

文章来源于: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.

  1. Go to Window-> Preferences-> Java-> Compiler
  2. 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

猜你喜欢

转载自blog.csdn.net/yangyangrenren/article/details/121175861