Java—如何从另一个类调用方法,将类名和方法名作为字符串
此方法定期调用Java—如何从另一个类调用方法,将类名和方法名作为字符串,java,arrays,invoke,Java,Arrays,Invoke,此方法定期调用 public static void stynax(String N[]) { if (N[1].equals("echo")) { echo.s(); main(); } if (N[1].equals("detectos")) { detectos.s(); main(); } if (N[1].equals("getuser")) { getuser.s(); main(); } if (N[1].equals("exit")) { exit
public static void stynax(String N[]) {
if (N[1].equals("echo")) { echo.s(); main(); }
if (N[1].equals("detectos")) { detectos.s(); main(); }
if (N[1].equals("getuser")) { getuser.s(); main(); }
if (N[1].equals("exit")) { exit.s(); main(); }
if (N[1].equals("makefile")) { makefile.s(); main(); }
if (N[1].equals("cd")) { cd.s(); main(); }
if (N[1].equals("system")) { system.s(); main(); }
main();
}
如何调用所有这些方法
system.s();
echo.s();
Ect,通过查看类是否存在,然后调用相应的方法。
N[1]始终是类名。存储此方法的类位于名为main的类中,而被调用的类位于名为Commands的不同包中
我似乎总是会遇到这个错误,当我试图创建一个类变量时,我认为这是主要的问题
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
因此,它永远无法调用该方法
简化
1) 程序以字符串形式获取类名,如N[1]
2) 它查看类是否存在
3) 如果类存在,它将以类N[1].s()的名称调用它
编辑:使用导入
导入java.io.ByteArrayOutputStream;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.io.PrintStream;
导入java.io.PrintWriter;
导入java.lang.reflect.InvocationTargetException;
导入java.lang.reflect.Method;
导入java.util.array
import cgameing.Commands.FileBrowser;
import cgameing.Commands.banner;
import cgameing.Commands.cd;
import cgameing.Commands.detectos;
import cgameing.Commands.echo;
import cgameing.Commands.exit;
import cgameing.Commands.getuser;
import cgameing.Commands.makefile;
import cgameing.Commands.system;
编辑结束:
这一条对任何想做同样事情的人都有效
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
谢谢大家您可以使用反射。
您有一个数组中的类名
您可以使用“类”和“方法”类。类可以确定该类是否存在,并且方法可用于调用您需要调用的方法
try {
Class<?> c = Class.forName(N[1]);
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
// if name matches use invoke method.
}
} catch (ClassNotFoundException x) {
//handle exception
}
试试看{
类别c=类别forName(N[1]);
对象t=c.newInstance();
方法[]allMethods=c.getDeclaredMethods();
对于(方法m:所有方法){
字符串mname=m.getName();
//如果名称匹配,则使用invoke方法。
}
}捕获(ClassNotFoundException x){
//处理异常
}
如果您需要查看更多详细信息,请咨询API。您可以使用反射。
您有一个数组中的类名
您可以使用“类”和“方法”类。类可以确定该类是否存在,并且方法可用于调用您需要调用的方法
try {
Class<?> c = Class.forName(N[1]);
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
// if name matches use invoke method.
}
} catch (ClassNotFoundException x) {
//handle exception
}
试试看{
类别c=类别forName(N[1]);
对象t=c.newInstance();
方法[]allMethods=c.getDeclaredMethods();
对于(方法m:所有方法){
字符串mname=m.getName();
//如果名称匹配,则使用invoke方法。
}
}捕获(ClassNotFoundException x){
//处理异常
}
如果您需要查看更多详细信息,请咨询API。您需要使用反射。试着做如下的事情。如果您的类位于不同的包中,请使用完全限定的类名,而不是
“XYZ”
import java.lang.reflect.*;
import java.lang.*;
public class ReflectionTest {
public static void main(String[] args)throws NoSuchMethodException,
ClassNotFoundException,
IllegalAccessException,
InvocationTargetException {
(Class.forName("XYZ")).getDeclaredMethod("ABC", null).invoke(null,null);
}
}
class XYZ
{
public static void ABC()
{
System.out.println("Lulz");
}
}
对于给定的用例,类位于命令
包中(如您在注释中所述)。然后,完全限定名将是命令。classname
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
你需要使用反射。试着做如下的事情。如果您的类位于不同的包中,请使用完全限定的类名,而不是
“XYZ”
import java.lang.reflect.*;
import java.lang.*;
public class ReflectionTest {
public static void main(String[] args)throws NoSuchMethodException,
ClassNotFoundException,
IllegalAccessException,
InvocationTargetException {
(Class.forName("XYZ")).getDeclaredMethod("ABC", null).invoke(null,null);
}
}
class XYZ
{
public static void ABC()
{
System.out.println("Lulz");
}
}
对于给定的用例,类位于命令
包中(如您在注释中所述)。然后,完全限定名将是命令。classname
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
如果可能的话,我建议您避免使用反射。更好的方法是定义您希望看到的命令-理想情况下是在
enum
中
例如:
enum Command {
CD(FileSystem::cd),
EXIT(Application::exit),
MAKEFILE(FileSystem::createFile),
...
private final Runnable runnable;
Command(Runnable runnable) {
this.runnable = runnable;
}
public void run() {
runnable.run();
}
}
如果愿意,您仍然可以使用该名称获取命令(如果在枚举中找不到该值,则会自动引发异常-这可能是您想要的):
或者直接调用命令,而不必知道它们委托给哪个方法:
Command.MAKEFILE.run();
如果您将在某个地方有一个
if
语句列表,那么您最好将其封装在enum
中,这比嵌入方法名要明确得多 如果可能,我建议您避免使用反射。更好的方法是定义您希望看到的命令-理想情况下是在enum
中
例如:
enum Command {
CD(FileSystem::cd),
EXIT(Application::exit),
MAKEFILE(FileSystem::createFile),
...
private final Runnable runnable;
Command(Runnable runnable) {
this.runnable = runnable;
}
public void run() {
runnable.run();
}
}
如果愿意,您仍然可以使用该名称获取命令(如果在枚举中找不到该值,则会自动引发异常-这可能是您想要的):
或者直接调用命令,而不必知道它们委托给哪个方法:
Command.MAKEFILE.run();
如果您将在某个地方有一个
if
语句列表,那么您最好将其封装在enum
中,这比嵌入方法名要明确得多 好的,每个人似乎都建议进行反射,至少有一种替代方法,这取决于您在编译时是否知道类和方法名
假设我们在某个类中有这个方法:
public void changeDirectory(String args) {
//do something
}
如果已知,则可以轻松使用方法引用:
HashMap<String, Consumer<String[]>> commands = new HashMap<>();
commands.put("cd", SomeClass::changeDirectory);
commands.get("cd").accept(args);
HashMap命令=newhashmap();
commands.put(“cd”,SomeClass::changeditory);
commands.get(“cd”).accept(args);
缺点是,方法签名必须相同。。。另一方面,如果您知道确切的方法,您可以使用switch语句直接调用它们
如果您想动态地执行此操作,反射的替代方法是MethodHandles。其优点是,它们只在创建时检查一次访问权限,并且有一些其他的优化,这些优化在大多数情况下都会使它们比反射更快
Class<?> dynamicallyFoundClass = Class.forName("some.package.SomeClass");
Class<?> fixedClass = SomeClass.class;
String methodName = "changeDirectory";
MethodType type = MethodType.methodType(void.class, String.class);
handles.put("cd", lookUp.findStatic(dynamicallyFoundClass, methodName, type));
handles.get("cd").invoke(args);
Class dynamicallyFoundClass=Class.forName(“some.package.SomeClass”);
Class fixedClass=SomeClass.Class;
String methodName=“changeditory”;
MethodType=MethodType.MethodType(void.class,String.class);
handles.put(“cd”,lookUp.findStatic(dynamicallyFoundClass,methodName,type));
句柄.get(“cd”).invoke(args);
但是,您必须使用的方法有多复杂取决于您在编译时知道的内容以及在运行时必须找到的内容。好的,每个人似乎都建议进行反射,至少