"Как вы проверяете безопасность типов вашего обобщенного API?"ИМХО, краткий ответ на ваш вопрос должен быть:
- Не используйте
@SuppressWarnings
- Убедитесь, что вы компилируете без предупреждений (или ошибок)
Более длинный ответ состоит в том, что «безопасность типов» не является свойством API, это свойство языка программирования и его системы типов .Обобщения Java 5 являются типобезопасными в том смысле, что они дают вам гарантию того, что у вас не возникнет ошибка типа (ClassCastException
) во время выполнения, если только она не происходит из операции приведения уровня пользователя (и если вы программируете с использованием дженериков, вы редконужно больше таких слепков).Единственный бэкдор - это использование необработанных типов для взаимодействия с кодом до Java 5, но в этих случаях компилятор выдаст предупреждения, такие как печально известное предупреждение «unchecked cast», чтобы указать, что безопасность типов может быть поставлена под угрозу.Однако, за исключением таких предупреждений, Java будет гарантировать безопасность типов.
Так что, если вы не являетесь автором компилятора (или не доверяете компилятору), кажется странным желать проверить «безопасность типов».В приведенном вами примере кода, если вы являетесь разработчиком ArrayList<T>
, вам следует только дать addAll
наиболее гибкую сигнатуру типа, которая позволит вам написать функционально правильную реализацию .Например, вы можете ввести аргумент как Collection<T>
, но также как Collection<? extends T>
, где последний предпочтительнее, поскольку он более гибкий.Хотя вы можете чрезмерно ограничивать свои типы, язык программирования и компилятор позаботятся о том, чтобы вы не могли написать что-то, что не является типобезопасным: например, вы просто не можете написать правильную реализацию для addAll
, где аргумент имеет тип Collection<?>
или Collection<? super T>
.
Единственное исключение, о котором я могу подумать, это когда вы пишете фасад для какой-то небезопасной части системы и хотите использовать дженерики для обеспечения каких-то гарантий использованияэтой части через фасад.Например, хотя отражение Java не контролируется как таковое системой типов, Java использует универсальные элементы в таких вещах, как Class<T>
, чтобы позволить некоторым отражающим операциям, таким как clazz.newInstance()
, интегрироваться ссистема типов.