Java 使用反射调用方法
Java invoke method using reflection
我正在尝试使用反射调用方法。
我正在调用的方法不是静态的,并且在我调用它的同一个 class 中。
我的代码的简化版本:
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
[...]
}
}
private void MethodOne() { ... };
private void MethodTwo() { ... };
[...]
private void MethodTwenty() { ... };
}
尽管存在包/class/方法,但我得到的是java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo()
。
谁能告诉我我做错了什么?
What I am getting is a java.lang.NoSuchMethodException:
correct.package.and.class.MethodTwo()...
您调用的 getMethod()
没有返回私有方法
假设 arg[0] 有正确的方法名称(否则你会得到 java.lang.NoSuchMethodException),这里必须做两件事:
你需要使用getDeclaredMethod(因为MethodOne是私有声明的)
您需要设置访问它的标志.setAccessible(true)
(这将允许您调用声明为私有的方法)
示例:
Method method;
try {
method = f.getClass().getDeclaredMethod("doThis");
method.setAccessible(true);
method.invoke(f);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
System.err.println("Opala, somethign went wrong here!");
}
您访问 method 的方式是正确的。
方法访问说明符是私有的。因此它抛出错误。
请将访问说明符更改为 public,它将起作用。
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (Exception e) {
}
}
public void MethodOne() { System.out.println("Method 1"); };
public void MethodTwo() { System.out.println("Method 2"); };
public void MethodTwenty() { System.out.println("Method 3"); };
}
如果您尝试访问私有方法或构造函数,则需要更改代码。
谢谢,
蒂鲁帕蒂 S
CLASS 从
调用方法
public class Computer {
private String brandName;
private int yearManufactured;
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public int getYearManufactured() {
return yearManufactured;
}
public void setYearManufactured(int yearManufactured) {
this.yearManufactured = yearManufactured;
}
}
实施CLASS
public class Test {
public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException{
Class curClass = Computer.class;
Method[] allMethods = curClass.getDeclaredMethods();
Computer myComputer = new Computer();
for(int c = 0; c < allMethods.length; c++){
Class[] parameterTypes = allMethods[c].getParameterTypes();
for(Class parameterType: parameterTypes){
System.out.println(parameterType.getName());
switch(parameterType.getName()){
case "java.lang.String":
allMethods[c].invoke(myComputer, "LENOVO");
break;
case "int":
allMethods[c].invoke(myComputer, 2021);
break;
}
}
}
System.out.println("BRAND NAME :"+myComputer.getBrandName());
System.out.println("YEAR MANUFACTURED: "+myComputer.getYearManufactured());
}
}
我正在尝试使用反射调用方法。
我正在调用的方法不是静态的,并且在我调用它的同一个 class 中。
我的代码的简化版本:
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
[...]
}
}
private void MethodOne() { ... };
private void MethodTwo() { ... };
[...]
private void MethodTwenty() { ... };
}
尽管存在包/class/方法,但我得到的是java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo()
。
谁能告诉我我做错了什么?
What I am getting is a java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo()...
您调用的 getMethod()
没有返回私有方法
假设 arg[0] 有正确的方法名称(否则你会得到 java.lang.NoSuchMethodException),这里必须做两件事:
你需要使用getDeclaredMethod(因为MethodOne是私有声明的)
您需要设置访问它的标志
.setAccessible(true)
(这将允许您调用声明为私有的方法)
示例:
Method method;
try {
method = f.getClass().getDeclaredMethod("doThis");
method.setAccessible(true);
method.invoke(f);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
System.err.println("Opala, somethign went wrong here!");
}
您访问 method 的方式是正确的。 方法访问说明符是私有的。因此它抛出错误。
请将访问说明符更改为 public,它将起作用。
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test instance = new Test();
if (args.length > 0) {
instance.doWork(args[0]);
}
}
private void doWork(String methodName) {
Method method;
try {
method = this.getClass().getMethod(methodName);
method.invoke(this);
} catch (Exception e) {
}
}
public void MethodOne() { System.out.println("Method 1"); };
public void MethodTwo() { System.out.println("Method 2"); };
public void MethodTwenty() { System.out.println("Method 3"); };
}
如果您尝试访问私有方法或构造函数,则需要更改代码。
谢谢, 蒂鲁帕蒂 S
CLASS 从
调用方法public class Computer {
private String brandName;
private int yearManufactured;
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public int getYearManufactured() {
return yearManufactured;
}
public void setYearManufactured(int yearManufactured) {
this.yearManufactured = yearManufactured;
}
}
实施CLASS
public class Test {
public static void main(String[] args) throws NoSuchMethodException,
InvocationTargetException, IllegalAccessException{
Class curClass = Computer.class;
Method[] allMethods = curClass.getDeclaredMethods();
Computer myComputer = new Computer();
for(int c = 0; c < allMethods.length; c++){
Class[] parameterTypes = allMethods[c].getParameterTypes();
for(Class parameterType: parameterTypes){
System.out.println(parameterType.getName());
switch(parameterType.getName()){
case "java.lang.String":
allMethods[c].invoke(myComputer, "LENOVO");
break;
case "int":
allMethods[c].invoke(myComputer, 2021);
break;
}
}
}
System.out.println("BRAND NAME :"+myComputer.getBrandName());
System.out.println("YEAR MANUFACTURED: "+myComputer.getYearManufactured());
}
}