如何使用 class 名称作为方法参数的类型

How to use class name as type for method argument

我最近 运行 在尝试使用反射使我的一个 bukkit 插件版本独立时遇到了一些麻烦。 问题是,我知道如何使用它的名称创建 class 的实例,但我不知道如何使用 class 名称作为方法或构造函数参数的类型.换句话说,我想改造这个:

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 ,所以我只知道 class 名称。因此,我必须使用 Class.forName 方法以及一个检测当前 bukkit 版本并将其附加到我已经知道的包名称的小算法,因此 net.minecraft.server 将变为 net.minecraft.server .v1_8_R1 也就是说,我在运行时只知道class这个名字。我知道,我不擅长解释...

更新答案:

您已在评论中阐明您只知道类型名称在运行时

字段类型(和构造函数参数)goat编译时 设置。使用运行时信息创建 Foo class 的唯一方法就是:在运行时生成它。没有声明稍后将由字符串填充的占位符的机制。

如果您绝对需要这样做,您可以调用的一些现有技术是 Tomcat(即时编译 JSP)和 Vert.x(生成 class 是即时的)。这将是非常重要的(当然,除非你只是花钱 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>();
// ...