【问题标题】:Java - Get correctly casted object from HashMapJava - 从 HashMap 获取正确转换的对象
【发布时间】:2013-05-01 04:00:57
【问题描述】:

我正在开发一个具有多个系统的应用程序(在我的情况下,系统是我的应用程序中处理特定任务的可加载组件,例如:翻译、配置处理、音频等...)。这些系统共享一些常用方法,所以我创建了一个接口:

public interface System {
    public void initialize();
    public void uninitialize();
}

但是每个系统都有自己的方法,对应于系统执行的任务。这是我的系统的两个示例

第一个存储设置:

public class SettingsSystem implements System {
    @Override
    public void initialize() {
        // few lines of code here
    }

    @Override
    public void uninitialize() {
        // few lines of code here
    }

    public Object getSetting(String key) {
        // returns a setting
    }
}

还有翻译的语言系统。

public class LanguageSystem implements System {

    @Override
    public void initialize() {
        // few lines of code here
    }

    @Override
    public void uninitialize() {
        // few lines of code here
    }

    public void setLanguage(String language) {
        // sets language
    }

    public boolean load( String name) {
        // loads a file
    }

    public String translate(String key) {
        // returns translation of a key
    }
}

我将 System 实例存储在静态 HashMap 中,因为我想在我的应用程序的任何地方访问它们。我创建了一个静态方法来通过一个键返回任何系统。

public class App {
    // note: System is the System interface I created
    private static Map<String, System> systems = new HashMap<String, System>();

    public static Object getSystem(String key) {
        return systems.get(key);
    }
}

如果我调用 App.getSystem() 方法,它会返回一个对象。所以如果我打电话...

App.getSystem("settings");

...它将正确的项目作为对象返回。但问题是,我不能调用 SettingsSystem 的 getSetting() 方法,因为它告诉我没有这个方法。

如果我这样实现:

public static System getSystem(String key) {
    return systems.get(key);
}

我可以调用 initialize() 或 uninitialize() 方法,但仍然没有可用的 getSettings() 方法。

我想要的是当我调用 App.getSystem() 方法时,我希望它返回其中包含的正确类型的对象。示例:

App.getSystem("settings"); // I want it to return a SettingsSystem object
// So I can do:
String width = App.getSystem("settings").getSetting("width");

App.getSystem("language"); // I want it to return a LanguageSystem object
// So I can do:
String welcome = App.getSystem("language").translate("hello_world");

这怎么可能?提前致谢。

更新

根据您的帮助,我决定为每个系统声明 getter 方法:

public SettingsSystem getSettingsSystem() {
    return (SettingsSystem) system.get("settings");
}

感谢您的建议!

【问题讨论】:

    标签: java interface casting hashmap


    【解决方案1】:

    您需要像这样转换为正确的类型:

    SettingsSystem settingSystem = null;
    System system = App.getSystem("settings");
    if (system instanceof SettingsSystem) {
        settingSystem = (SettingSystem) system;
    }
    settingSystem.getSetting("width");
    

    当然,通过相关的null 检查等来执行此操作。

    如果可以避免强制转换,我更喜欢。你能用实现类保留两个单独的映射吗?

    或者,由于您似乎有多个 System 的实现,请使用 Patricia Shanahan 的解决方案 #2,它可以隔离强制转换。

    【讨论】:

      【解决方案2】:

      表达式的类型,包括调用返回的类型,在编译时是固定的。你不能让同一个对象中的同一个方法有几种不同的返回类型。

      你有两个选择:

      1. 返回类型 Object,并在调用者中强制转换。
      2. 为每种类型声明不同的 getXXXSystem 方法。 getLanguageSystem 将具有返回类型 LanguageSystem。

      【讨论】:

        【解决方案3】:

        那是因为System 类没有那个方法。您需要显式转换为特定类 SettingSystemLanguageSystem 才能使用此方法。

        【讨论】:

          【解决方案4】:

          getSystem() 方法返回一个 System 实例,因此您只能访问 System 接口中定义的方法。

          如果要访问具体实现类中定义的方法,必须先将对象强制转换为该类

          【讨论】:

            猜你喜欢
            • 2020-06-10
            • 1970-01-01
            • 2017-02-26
            • 1970-01-01
            • 2022-11-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多