Можно ли переопределить метод Set () в Set? - PullRequest
1 голос
/ 18 ноября 2011

Я играл с отражением Java и хотел создать механизм кэширования методов из методов, объявленных в разных классах. Чтобы предотвратить случайное поведение, я хочу запретить загрузку методов с одинаковой подписью в кэш (метод, объявленный в разных классах, может иметь одинаковую подпись).

Единственный способ, который я нашел, это переопределить метод contains () объекта Set, где я кеширую методы.

Опасно ли это делать? У вас есть идея получше?

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 ]

2 голосов
/ 18 ноября 2011

Просто используйте комбинацию следующего для вашего ключа кеша:

имя класса + имя метода + типы параметров метода

1 голос
/ 18 ноября 2011

Вполне нормально переопределить метод "contains ()" - однако, как правило, он не нужен.Цель метода contains () - просто проверить, существует ли уже эквивалентный объект в коллекции.

Метод «равно» для вашей конкретной коллекции объектов будет использоваться для выяснения этого.

Однако, если вы хотите, чтобы пользовательское поведение для содержимого, которое НЕ МОЖЕТ быть встроено в объект, возможно, стоит взломать метод contains ().Я думаю, учитывая тот факт, что вы пытаетесь кэшировать java-методы, вы можете захотеть приклеить логику «содержит» в набор, содержащий эти методы .... Однако, это не совсем понятно.

0 голосов
/ 18 ноября 2011

Я согласен с вышеуказанным постом (@ jayunit100).Тем не менее, я бы не стал переопределять функции метода () для этого.Вместо этого я написал бы реализацию Comparator и использовал бы SortedSet.Например:

SortedSet<Method> cachedMethods = new TreeSet<Method>(new Comparator<Method>() {
    // compare() implementation omitted
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...