Если вы определяете его в интерфейсе, то он должен быть реализован в любом классе, который хочет реализовать интерфейс. Таким образом, вы не сможете обойти реализацию onDuplicateKeyUpdate
в любом классе, который реализует интерфейс Insert<R extends Record>
.
Вы указали R extends Record
в интерфейсе, и это становится частью контракта, что означает, что можно использовать любой подтип Record
. Я не могу придумать способ добавить дополнительное ограничение с использованием обобщений, которые ограничивают его только типом UpdatableRecord
.
Кроме того, вы не можете принимать решения в своем интерфейсе на основе типа R
, поскольку эта информация исчезает из-за стирания типа.
Мне кажется, что ваша проблема связана с разницей между Record
и UpdatableRecord
. Поскольку интерфейс предназначен для генерального контракта, я не думаю, что специфичное для типа поведение должно быть в вашем интерфейсе. Таким образом, вы должны найти способ разрешить разницу другим способом. Моим решением было бы реализовать метод (который возвращает boolean
) в интерфейсе Record
с именем canUpdate
, который можно использовать в onDuplicateKeyUpdate
. Таким образом, вы можете выбросить UnsupportedOperationException
, если запись не поддерживает эту операцию или ничего не делать (если вы хотите избежать исключения и если ничего не делать, имеет смысл в контексте вашей бизнес-логики).
Это с моей головы; может быть лучшее решение. Я постараюсь еще об этом подумать.
EDIT
Я немного подумал об этом, и именно твоя последняя редакция заставила меня задуматься над этим. <R extends Record>
относится ко всему классу. Поэтому нет способа переопределить или сузить его в контексте определенного метода. Аннотация, подобная той, которую вы упомянули, должна быть реализована на уровне компилятора, и на этом уровне я даже не уверен, будет ли у вас доступ к типу R (из-за стирания типа). Так что то, что вы говорите, может быть невозможным.
На концептуальном уровне то, что вы просите , не должно быть возможным IMO, потому что вы указываете исключение из контракта в пределах вашего контракта. Также кажется, что детали реализации проникают в ваш интерфейс, потому что интерфейсы не должны пытаться выяснить, что что-то может или не может делать; это должно быть решено в конкретной реализации.