如何使用 Class.forName() 的构造函数
how do I use the constructor for Class.forName()
问题是当我为 Minecraft 服务器构建插件时。因为那是我的事,那个包总是随着不同的版本而改变,比如 net.minecraft.1_8R1
,但是里面的 class 文件永远不会改变。所以我试图通过 Class.forName("net.minecraft." + getVersion() + "PacketPlayOutTitle")
找到 class。我已经制作了自己的 getVersion()
方法。但是我如何使用这个 PacketPlayOutTitle 构造函数,而不导入它,这样我的插件就会与不同版本的服务器兼容。请,谢谢。
使用反射。
Class<?> packetClass = Class.forName("net.minecraft." + getVersion() + "PacketPlayOutTitle");
Object packet = packetClass.newInstance();
编辑:这里是没有导入的例子。使用反射调用方法。
public class Bar {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//find class
Class<?> fooClass = Class.forName("foo.Foo");
//find constructor for given arguments
Constructor<?> fooConstructor = fooClass.getConstructor(String.class, int.class);
//call constructor
Object foo = fooConstructor.newInstance("FooBar", 100);
//find method
Method getFooMethod = fooClass.getDeclaredMethod("getFoo");
Method setFooMethod = fooClass.getDeclaredMethod("setFoo", String.class);
Method getBarMethod = fooClass.getDeclaredMethod("getBar");
Method setBarMethod = fooClass.getDeclaredMethod("setBar", int.class);
//call method
Object fooResult = getFooMethod.invoke(foo);
System.out.println(fooResult);
Object barResult = getBarMethod.invoke(foo);
System.out.println(barResult);
setFooMethod.invoke(foo, "BarFoo");
setBarMethod.invoke(foo, 200);
fooResult = getFooMethod.invoke(foo);
System.out.println(fooResult);
barResult = getBarMethod.invoke(foo);
System.out.println(barResult);
}
}
public class Foo {
private String foo;
private int bar;
public Foo(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
}
这产生输出:
FooBar
100
BarFoo
200
问题是当我为 Minecraft 服务器构建插件时。因为那是我的事,那个包总是随着不同的版本而改变,比如 net.minecraft.1_8R1
,但是里面的 class 文件永远不会改变。所以我试图通过 Class.forName("net.minecraft." + getVersion() + "PacketPlayOutTitle")
找到 class。我已经制作了自己的 getVersion()
方法。但是我如何使用这个 PacketPlayOutTitle 构造函数,而不导入它,这样我的插件就会与不同版本的服务器兼容。请,谢谢。
使用反射。
Class<?> packetClass = Class.forName("net.minecraft." + getVersion() + "PacketPlayOutTitle");
Object packet = packetClass.newInstance();
编辑:这里是没有导入的例子。使用反射调用方法。
public class Bar {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//find class
Class<?> fooClass = Class.forName("foo.Foo");
//find constructor for given arguments
Constructor<?> fooConstructor = fooClass.getConstructor(String.class, int.class);
//call constructor
Object foo = fooConstructor.newInstance("FooBar", 100);
//find method
Method getFooMethod = fooClass.getDeclaredMethod("getFoo");
Method setFooMethod = fooClass.getDeclaredMethod("setFoo", String.class);
Method getBarMethod = fooClass.getDeclaredMethod("getBar");
Method setBarMethod = fooClass.getDeclaredMethod("setBar", int.class);
//call method
Object fooResult = getFooMethod.invoke(foo);
System.out.println(fooResult);
Object barResult = getBarMethod.invoke(foo);
System.out.println(barResult);
setFooMethod.invoke(foo, "BarFoo");
setBarMethod.invoke(foo, 200);
fooResult = getFooMethod.invoke(foo);
System.out.println(fooResult);
barResult = getBarMethod.invoke(foo);
System.out.println(barResult);
}
}
public class Foo {
private String foo;
private int bar;
public Foo(String foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
}
这产生输出:
FooBar
100
BarFoo
200