反射的哈希码?

时间:2013-05-03 17:41:14

标签: java reflection hashcode

我有

interface Module {
    List<String> parse();
}

接口有几种实现,在应用程序中我希望有HashSet<Module>,确保每个模块只有一个实例。为此,我需要为每个班级提供适当的hashCodehashCode的正确实现将为一个模块类的各种实例返回相同的常量,但对于不同的模块则返回不同的实例。

要创建一个漂亮的设计解决方案,我想从模块的名称计算hashCode,如:

public int hashCode() {
    return ConcreteModule.class.getName().hashCode();
}

但是这个代码对于接口的每个实现都是一样的...我的想法是创建一个实现哈希码的抽象模块,但是有可能达到扩展这个抽象类的类的名称吗? 像:

public abstract class AbstractModule implements Module {
    public int hashCode() {
        // get the class name of class extending the abstract module
        // and return hashcode of its string name
    }
}

然后

public class ConcreteModule extends AbstractModule implements Module {
    // implementation of parse() no need to create hashcode for each module
}

您是否建议为每个模块创建hashCodes,或者是否可以创建我正在尝试的内容?欢迎提出任何建议或建议。提前致谢

3 个答案:

答案 0 :(得分:2)

经过一番思考,你想要做的就是关掉课堂上的地图,而不是实例....

HashMap<Class<? extends Module>, <Module>> mymap = .....

然后,每个类类型只有一个值。你可以用:

mymap.put(module.class(), module);

答案 1 :(得分:1)

怎么样:

return getClass().getName().hashCode();

虽然,您可以轻松使用:

return getClass().hashCode();

答案 2 :(得分:1)

您可以像下面这样简单地实现它:

@Override
public final int hashCode() {
    return this.getClass().getName().hashCode();
}

@Override
public final boolean equals(Object other) {
    if (other == this) {
        return true;
    }
    if (other == null) {
        return false;
    }
    return other.getClass().equals(this.getClass());
}

但我不确定这是最好的主意。此外,您不能保证接口的所有实现都扩展您的抽象类。

您可以简单地维护Map<Class<? extends Module>, Module>。每个模块实现都会将自己添加到您的注册表中,如果模块的类已经在地图中,您只需拒绝或忽略新的模块实例。