java中的反射并尝试复制控制器/操作
是否有一种方法可以仅基于字符串名实例化类?我理解反射需要包名和完全限定名。但如果给你: /ClassName/methodName?参数=x 你把它撕成这样:java中的反射并尝试复制控制器/操作,java,reflection,Java,Reflection,是否有一种方法可以仅基于字符串名实例化类?我理解反射需要包名和完全限定名。但如果给你: /ClassName/methodName?参数=x 你把它撕成这样: callClass(ClassName).callMethod(methodName).params(…)(在本例中,.params()表示方法) 在php中,这非常容易。我理解这在Java中非常容易,因为您需要类的完全限定名,因为包允许您多次定义单个名称,并且这种方法可能会导致一些严重的性能问题 如果你想知道我如何以这种或那种方式实现这
callClass(ClassName).callMethod(methodName).params(…)
(在本例中,.params()
表示方法)
在php中,这非常容易。我理解这在Java中非常容易,因为您需要类的完全限定名,因为包允许您多次定义单个名称,并且这种方法可能会导致一些严重的性能问题
如果你想知道我如何以这种或那种方式实现这样的目标,你需要一个完全限定的类名 您可以按照约定执行此操作—将类名附加到预定的包名(或假定为默认包)
或者,您可以执行一些类加载器魔术,仅基于部分名称查找完整的类名(假设名称不含糊)。换句话说,您的类加载器将跟踪所有加载的类,然后您可以使用您的部分名称与这些类名进行匹配。但是,对于大多数应用程序来说,这是严重的过度使用。正如@DNA前面所回答的,您总是需要一个完全限定的类名。然后是反思,这既慢又痛苦。以番石榴为例,你可以这样做:
public static void main(String[] args) throws Exception {
String myClassName = "App";
String methodName = "method";
Object[] params = {};
ClassPath cp = ClassPath.from(ClassLoader.getSystemClassLoader());
ImmutableSet<ClassPath.ClassInfo> cls = cp.getTopLevelClasses();
for (ClassPath.ClassInfo cl : cls) {
if(cl.getSimpleName().equals(myClassName)) {
Class<?> clazz = cl.load();
for (Method m : clazz.getMethods()) {
if(m.getName().equals(methodName)) {
Object instance = clazz.newInstance();
// invoke method - prints Hello
m.invoke(instance, params);
}
}
}
}
}
public void method() {
System.out.println("Hello!!!");
}
publicstaticvoidmain(字符串[]args)引发异常{
字符串myClassName=“App”;
String methodName=“方法”;
对象[]参数={};
ClassPath cp=ClassPath.from(ClassLoader.getSystemClassLoader());
ImmutableSet cls=cp.GetToLevel类();
对于(ClassPath.ClassInfo cl:cls){
if(cl.getSimpleName().equals(myClassName)){
类clazz=cl.load();
对于(方法m:clazz.getMethods()){
if(m.getName().equals(methodName)){
对象实例=clazz.newInstance();
//调用方法-打印Hello
m、 调用(实例、参数);
}
}
}
}
}
公开作废法(){
System.out.println(“你好!!!”;
}
相当残暴。抛出许多必须处理的异常。如果你有一个更大的项目,使用这样的东西会花费很多时间。不,你需要完全限定的类名。否则,无法确定您想要哪种类方法。另外,请查看反射中涉及的各种类型的Javadoc,即
class
和method
。除非方法是静态的,否则您需要类的实例来调用其上的方法。