【问题标题】:Java class extend another class using reflection (bukkit)Java 类使用反射扩展另一个类 (bukkit)
【发布时间】:2018-10-28 11:43:06
【问题描述】:

我正在尝试为我的 bukkit 插件制作 Anvil GUI。我正在尝试使我的代码跨版本兼容。但是FakeAnvil类需要扩展ContainerAnvil类,而这个类在NMS包中……有什么办法可以用反射扩展类吗?

这是我的代码:

package me.raymondliu1;

import java.lang.reflect.Constructor;
import org.bukkit.Bukkit;
//These five import is making the plugin not cross-version compatible
import net.minecraft.server.v1_8_R1.BlockPosition;
import net.minecraft.server.v1_8_R1.ContainerAnvil;
import net.minecraft.server.v1_8_R1.EntityHuman;
import net.minecraft.server.v1_8_R1.PlayerInventory;
import net.minecraft.server.v1_8_R1.World;


//problem 1
public final class FakeAnvil extends ContainerAnvil {
static Class<?> entityHumanClass;
static Class<?> BlockPositionClass;
static Class<?> ContainerAnvilClass;
static Constructor<?> bpc;
static Constructor<?> cac;
static{
    try {
        entityHumanClass = getNMSClass("EntityHuman");
        BlockPositionClass = getNMSClass("BlockPosition");
        ContainerAnvilClass = getNMSClass("ContainerAnvil");
        cac = ContainerAnvilClass.getConstructor(PlayerInventory.class,World.class,BlockPositionClass,entityHumanClass);
        bpc = BlockPositionClass.getConstructor(int.class,int.class,int.class);

    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    }
}
private static Class<?> getNMSClass(String nmsClassString) throws ClassNotFoundException {
    String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
    String name = "net.minecraft.server." + version + nmsClassString;
    Class<?> nmsClass = Class.forName(name);
    return nmsClass;
}
public FakeAnvil(Object entityHuman) throws Exception {
    //Problem 2
    super((PlayerInventory)entityHumanClass.getField("inventory").get(entityHuman), (World)entityHumanClass.getField("inventory").get("world"), (BlockPosition)bpc.newInstance(0,0,0), (EntityHuman)entityHuman);

}
@Override
public boolean a(EntityHuman entityHuman) {    
    return true;
}
}

【问题讨论】:

  • 您可以实现该类的两个版本,并且只加载与检测到的版本兼容的一个。 Java 类在首次使用时被加载,因此可卸载的类在您尝试加载之前不会产生问题。
  • 在 bukkit 中流行的解决方案是为每个 NMS 版本和通用 API 创建模块,因此您稍后才使用反射加载正确的模块并通过通用 api 使用它,其他想法是在运行时创建类使用 ByteBuddy 或 Javassist 等库

标签: java reflection minecraft extends bukkit


【解决方案1】:

很遗憾,您不能使用反射使一个类从另一个类或接口继承。

但是,您可以修改 NMS 包中的内容(不推荐)并使用它来代替。

【讨论】:

  • 是否可以为不同版本的我的世界创建一个 FakeAnvil 类?我会因为导入的类而出错吗?
  • 能拿到NMS类应该没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多