java - <T extends SomeClass> 未返回 T 类型的对象。找不到适合我的解决方案

标签 java generics extends

我有以下类(class)。我试图让 getConfig() 返回指定的类型,但是,它只返回 BaseConfig。假设我有扩展 BaseConfig 的 MyConfig,我希望该方法返回 MyConfig 而不是 BaseConfig。非常感谢任何帮助,因为我似乎找不到适合我的合适解决方案。

public class LoadedMap<T extends BaseConfig> implements GameMap {
    private File world;
    private Class<T> configClass;
    private T config;

    public LoadedMap(File world, Class<T> configClass) {
        this.world = world;
        this.configClass = configClass;
        this.loadConfig();
    }

    @Override
    public File getWorld() {
        return this.world;
    }

    @Override
    public String getMapName() {
        return this.config.getMapName();
    }

    @Override
    public String getMapAuthor() {
        return this.config.getMapAuthor();
    }

    public <T extends BaseConfig> T getConfig() {
        return configClass.cast(config);
    }

    private void loadConfig() {
        this.config = JsonConfig.load(new File(world + File.separator + "map.json"), configClass);
    }
}

构成我正在开发的系统的一些附加类:

public class MapManager<T extends BaseConfig> {
    private Class<T> configClass;
    private List<LoadedMap<T>> maps = new ArrayList<>();
    private LoadedMap<T> current = null;

    public MapManager(Class<T> configClass) {
        this.configClass = configClass;
    }

    public CycleCompleteEvent cycle() throws MapNotFoundException{
        load();
        if (maps.size() == 0) {
            throw new MapNotFoundException();
        }

        LoadedMap previous = current;
        if (maps.contains(current) && maps.indexOf(current) != maps.size() - 1) {
            current = maps.get(maps.indexOf(current) + 1);
        } else {
            current = maps.get(0);
        }

        MapSelectedEvent mapSelectedEvent = new MapSelectedEvent(current);
        Bukkit.getPluginManager().callEvent(mapSelectedEvent);

        if (mapSelectedEvent.getMap() != null) {
            current = mapSelectedEvent.getMap();
        }

        init();
        if (current != null) {
            clean(previous);
        }

        CycleCompleteEvent cycleCompleteEvent = new CycleCompleteEvent(current);
        Bukkit.getPluginManager().callEvent(cycleCompleteEvent);
        return cycleCompleteEvent;
    }

    private void init() {
        prepareWorld();
    }

    private void init(LoadedMap<T> map) {
        if (current != null) {
            clean(current);
        }

        current = map;
        prepareWorld();
    }

    private void prepareWorld() {
        WorldCreator creator = new WorldCreator(current.getWorld().getName());
        Bukkit.getPluginManager().callEvent(new PreMapLoadEvent(current, creator));
        World world = Bukkit.createWorld(creator);
        world.setAutoSave(false);
        Bukkit.getPluginManager().callEvent(new PostMapLoadEvent(current, world));
    }

    private void clean(LoadedMap map) {
        if (Bukkit.getWorlds().contains(map.getWorld().getName())) {
            Bukkit.unloadWorld(map.getWorld().getName(), false);
        }
    }

    public void load() {
        File worldContainer = Bukkit.getWorldContainer();
        for (File file : worldContainer.listFiles()) {
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    if (f.getName().equals("map.json")) {
                        for (LoadedMap loadedMap : maps) {
                            if (loadedMap.getWorld() == file) {
                                continue;
                            }
                        }

                        maps.add(new LoadedMap<>(file, configClass));
                    }
                }
            }
        }
    }

    public Class<T> getConfigClass() {
        return configClass;
    }

    public List<LoadedMap<T>> getMaps() {
        load();
        return maps;
    }

    public LoadedMap<T> getCurrent() {
        return current;
    }
}

还有一个:

public abstract class Game<T extends BaseConfig> extends BukkitRunnable {

    private Plugin plugin;
    private boolean cancelled = false;
    private MapManager<T> mapManager;

    public Game(Plugin plugin, Class<T> configClass) {
        this.plugin = plugin;
        this.mapManager = new MapManager(configClass);
        this.runTaskTimer(plugin, 1, 1);
    }

    public abstract void run();

    @Override
    public void cancel() {
        if (this.cancelled) {
            return;
        }

        this.cancelled = true;
        Bukkit.getScheduler().cancelTask(getTaskId());
    }

    public Plugin getPlugin() {
        return plugin;
    }

    public boolean isCancelled() {
        return cancelled;
    }

    public MapManager getMapManager() {
        return mapManager;
    }
}

最佳答案

您正在使您的方法通用,但它不应该是:该类已经是通用的。它应该简单地声明为

public T getConfig() {
    return configClass.cast(config);
}

这样,该方法返回的类型 T 就是在类级别定义的类型 T。按照您的方式,T 是另一种泛型类型,特定于与类泛型类型同名但不相同的方法。 IE。它相当于

public <U extends BaseConfig> U getConfig() {
    return configClass.cast(config);
}

关于java - <T extends SomeClass> 未返回 T 类型的对象。找不到适合我的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28137565/

相关文章:

ios - 将类扩展继承子句迁移到协议(protocol)扩展

Scala不变的泛型类型参数被方法参数类型忽略,具体取决于参数是文字表达式还是变量

php - 检查扩展

java - 我如何在 Java 中读取使用 libreoffice 构建的 HSQL 数据库?

java - 如何从 Eclipse 将 Maven 项目的 WAR 部署到 JBoss 服务器?

c# - 在泛型类实例化上创建了多少个实例?

java - 为什么我们扩展 JpaRepository 接口(interface)而不实现它

Java 启动在第二次运行时失败 : java. lang.NullPointerException

java - 执行ExecutorService时出现NullPointerException

T 和 ? 之间的 Java 泛型区别?延伸 T