我最近在尝试使用反射使我的 bukkit 插件版本独立时遇到了一些麻烦。 问题是,我知道如何使用类的名称来创建类的实例,但我不知道如何使用类名作为方法或构造函数参数的类型。换句话说,我想改变这个:
public class Foo{
private Goat goat;
public Foo(Goat goat){
this.goat=goat;
}
像这样:
public class Foo{
private Class.forName("mypackage.Goat") goat;
public Foo(Class.forName("mypackage.Goat") goat){
this.goat=goat;
}
老实说,我不知道这是否可能,但这对加快我的开发有很大帮助。
编辑:
我的情况比我之前介绍的要复杂一些。这就是我实际上无法使用泛型的原因。我上面展示的“Goat”类型实际上是我不知道的包内的一个类,所以我只知道类名。因此,我必须使用 Class.forName 方法以及一个小算法来检测当前的 bukkit 版本并将其附加到我已经知道的包名称中,因此 net.minecraft.server 将变为 net.minecraft.server.v1_8_R1 换句话说,我只知道运行时的类名。我知道,我懒得解释...
最佳答案
更新答案:
您已在评论中澄清,您仅在运行时才知道类型名称。
字段的类型(和构造函数参数)goat
在编译时设置。使用运行时信息创建 Foo 类的唯一方法就是:在运行时生成它。没有机制可以声明稍后将由字符串填充的占位符。
如果您绝对需要这样做,您可以引用的一些现有技术是 Tomcat(它即时编译 JSP)和 Vert.x(它即时生成类)。这将是非常重要的(当然,除非您只是使用 javac
)。
原始答案:
您可以使用generics来做到这一点:
public class Foo<T> {
private T goat;
public Foo(T goat){
this.goat=goat;
}
}
用法:
Foo<Goat> f = new Foo<>(); // Or new Foo<Goat>() (earlier Java versions didn't support the <> form)
现在,f
期望 goat
是 Goat
。
这就像您使用集合框架中的某些内容一样:
List<String> strings = new List<String>();
List<Date> dates = new List<Date>();
// ...
关于java - 如何使用类名作为方法参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36451174/