Почему Hamcrest `match` метод использует Object как тип ввода и не использует тип generi c в качестве ввода - PullRequest
0 голосов
/ 12 февраля 2020

Я новичок в Java, изучаю фреймворк Hamcrest.

Я прочитал код интерфейса Matcher и не понимаю комментарий и сигнатуру метода matches(Object actual). Я ожидал, что это будет matches(T actual), и использую тип c типа T вместо Object, который принимает все.

Это исходный код: https://github.com/hamcrest/JavaHamcrest/blob/master/hamcrest/src/main/java/org/hamcrest/Matcher.java

для метода matches:

public interface Matcher<T> extends SelfDescribing {

/**
     * Evaluates the matcher for argument <var>item</var>.
     *
     * This method matches against Object, instead of the generic type T. This is
     * because the caller of the Matcher does not know at runtime what the type is
     * (because of type erasure with Java generics). It is down to the implementations
     * to check the correct type.
     *
     * @param actual the object against which the matcher is evaluated.
     * @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
     *
     * @see BaseMatcher
     */
    boolean matches(Object actual);

Чтение комментария над методом показывает, что это сделано намеренно, и я не понимаю, почему. Я знаю, что такое тип стирания в java. Но все же я не понимаю, почему разработчик Hamcrest решил, что лучше использовать Object в качестве входных данных, а не тип * generic c для интерфейса, который объявлен как generi c public interface Matcher<T> extends SelfDescribing

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Вы правы, сначала вы ожидаете T вместо Object, но, зная, что Generics являются функцией времени компиляции и недоступны во время выполнения (когда тесты запускаются и требуется сопоставление) (см. Тип Erasure) имеет смысл подчеркнуть тот факт, что технически это может быть что-то, что не является T, что вынуждает вас проверять создание более четких сообщений об ошибках в этом случае.

Тип Erasure (перефразировано с Oracle):

Стирание типа обеспечивает отсутствие дополнительных классов, созданных для различных обобщений. Он

  • заменяет все типы generic c на их границы или объекты.
  • представляет автоматы c casts
  • создает методы адаптера для сохранения полиморфизма.

Так что не будет никаких накладных расходов.

0 голосов
/ 13 февраля 2020

Q:

Я не понимаю, почему.

A: (из JavaDocs)

Это потому, что вызывающий абонент Matcher не знает во время выполнения, что это за тип (из-за стирания типа с помощью Java generics). Это зависит от реализаций, чтобы проверить правильный тип.

также из JavaDocs:

При использовании Hamcrest нет никакой гарантии относительно того, как часто matches() или describeMismatch() будет называться

Вы должны взглянуть на реализацию Hamcrest-Libs.
Итак, ваша реализация matches() называется внутренне Hamcrest (с любым объектом). Во время выполнения Hamcrest не имеет возможности узнать (и найти!) Правильный метод matches(...), потому что обобщения были очищены. Вам нужно проверить себя, действительно ли пройденный объект (от Hamcrest) действительно совпадает. Это не имеет ничего общего с Hamcrest.

Cheers!

...