是否可以覆盖Set的contains()方法?

时间:2011-11-17 23:26:42

标签: java reflection collections

我正在玩Java反射,我想从不同类中声明的方法创建一个方法缓存机制。为了防止随机行为,我想禁止加载具有相同签名的方法到Cache(在不同类中声明的方法可以具有相同的签名)。

我发现这样做的唯一方法是覆盖Set缓存方法的contains()方法。

这样做有危险吗?你有更好的想法来实现这个目标吗?

private final Set<Method> methodsCache;

public MyMethodCachingClass(Set<Class<?>> classes) {
    methodsCache = new HashSet<Method>(){
        private static final long serialVersionUID = -1467698582662452923L;

        /**
        * Overwriting the contains method of this Set so that we don't allow multiple methods with the same signature,
        * even if they are declared in different classes.
        */
        @Override
        public boolean contains(Object o) {
            if (!(o instanceof Method)) {
                return false;
            }

            Method method = (Method) o;
            for (Method m : this) {
                if (method.getName().equals(m.getName()) && method.getParameterTypes().equals(m.getParameterTypes())) {
                    return true;
                }
            }
            return false;
        }

    };

    for (Class<?> c : classes) {
        for (Method m : c.getDeclaredMethods()) {
            if (methodsCache.contains(m)) {
                throw new IllegalArgumentException("The method " + m.getName() + " exists with the same signature in two different classes.");
            }
            methodsCache.add(m);
        }
    }
}

谢谢!

3 个答案:

答案 0 :(得分:2)

只需将以下组合用于缓存密钥:

类名+方法名+方法参数类型

答案 1 :(得分:1)

完全可以覆盖“contains()”方法 - 但是,它通常是不必要的。 contains()方法的目的只是检查集合中是否已存在等效对象。

您的特定对象集合的“等于”方法将用于确定这一点。

但是,如果您希望包含的自定义行为不能嵌入到对象中,那么破解contains()方法可能是值得的。我认为,鉴于您正在尝试缓存java方法,您可能希望将“包含”逻辑粘贴到包含这些方法的集合中。但是,它并不完全清楚。

答案 2 :(得分:0)

我同意上述帖子(@ jayunit100)。但是,我不会为此覆盖contains()。相反,我会编写Comparator的实现并使用SortedSet。例如:

SortedSet<Method> cachedMethods = new TreeSet<Method>(new Comparator<Method>() {
    // compare() implementation omitted
});