我正在使用Java反射,我想从不同类中声明的方法创建一个方法缓存机制。为了防止随机行为,我想禁止将具有相同签名的方法加载到缓存(在不同类中声明的方法可以具有相同的签名)。
我发现这样做的唯一方法是重写我缓存方法的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);
}
}
}
谢谢!
只需使用以下组合作为缓存键:
类名+方法名+方法参数类型
重写"contains()"方法是完全可以的——但是,这通常是不必要的。contains()方法的目的只是检查集合中是否已经存在等效对象。
将使用特定对象集合的"equals"方法来确定这一点。
然而,如果你想为不能嵌入到对象中的包含定制行为,那么修改contains()方法可能是值得的。我认为,考虑到您正在尝试缓存java方法的事实,您可能希望将"contains"逻辑粘合到包含这些方法....的集合中然而,这并不完全清楚。
我同意上述帖子(@jayunit100)。但是,我不会为此重写contains()。相反,我将编写Comparator的实现并使用SortedSet。如:
SortedSet<Method> cachedMethods = new TreeSet<Method>(new Comparator<Method>() {
// compare() implementation omitted
});