Что такое стирание и сырые типы raw type необработанный тип

Что такое необработанный тип и почему мы не должны его использовать?

Вопросов:

Что такое сырой тип?

Спецификация языка Java определяет необработанный тип следующим образом:

JLS 4.8 Необработанные типы

Необработанный тип определяется как один из:

Тип ссылки, который формируется путем взятия имени объявления универсального типа без сопровождающего списка аргументов типа.

Тип массива, тип элемента которого является необработанным типом.

Вот пример для иллюстрации:

mt имеет необработанный тип (и генерирует предупреждение о компиляции) по первому пункту в приведенном выше определении; inn также имеет необработанный тип по третьему пункту.

mt1 и mt2 оба объявлены с фактическими параметрами типа, поэтому они не являются необработанными типами.

Что такого особенного в необработанных типах?

По сути, необработанные типы ведут себя так же, как и до появления дженериков. То есть, следующее является полностью законным во время компиляции.

Приведенный выше код работает просто отлично, но предположим, что у вас также есть следующее:

Смотрите также

Чем необработанный тип отличается от использования в качестве параметров типа?

Ниже приводится цитата из Effective Java 2nd Edition, пункт 23. Не используйте необработанные типы в новом коде :

Смотрите также

Чем необработанный тип отличается от использования в качестве параметра типа?

Рассмотрим следующий вариант предыдущего фрагмента:

Вернуться к JLS 4.8:

Суперклассы (соответственно, суперинтерфейсы) необработанного типа являются стиранием суперклассов (суперинтерфейсов) любой из параметризаций универсального типа.

Возьмите следующий пример:

JLS 4.6 продолжает объяснять следующее:

Возвращаемый тип метода и параметры типа универсального метода или конструктора также стираются, если сигнатура метода или конструктора удалена.

Удаление подписи универсального метода не имеет параметров типа.

Если это небезопасно, почему разрешено использовать необработанный тип?

Вот еще одна цитата из JLS 4.8:

Использование необработанных типов допускается только в качестве уступки совместимости устаревшего кода. Использование необработанных типов в коде, написанном после введения универсальности в язык программирования Java, настоятельно не рекомендуется. Вполне возможно, что будущие версии языка программирования Java будут запрещать использование необработанных типов.

Effective Java 2nd Edition также имеет следующее:

Учитывая, что вы не должны использовать необработанные типы, почему разработчики языка разрешили это? Для обеспечения совместимости.

Есть ли исключения?

К сожалению, из-за непатентованного универсального кода Java есть два исключения, где необработанные типы должны использоваться в новом коде:

Смотрите также

Что такое необработанные типы в Java, и почему я часто слышу, что они не должны использоваться в новом коде?

Хотя это работало большую часть времени, ошибки все же случались

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

Более сложный сравниваемый интерфейс:

Обратите внимание, что невозможно реализовать CompareAble интерфейс compareTo(MyCompareAble) с необработанными типами. Почему вы не должны использовать их:

Что делает компилятор: Generics обратно совместимы, они используют те же классы Java, что и необработанные типы. Магия происходит в основном во время компиляции.

Будет скомпилировано как:

Это тот же код, который вы написали бы, если бы использовали непосредственные типы. Хотя я не уверен, что происходит с CompareAble интерфейсом, я предполагаю, что он создает две compareTo функции, одну из которых принимает a, MyCompareAble а другую принимает Object и передает его первой после приведения.

Какие альтернативы необработанным типам: Используйте дженерики

Если фактический аргумент типа опущен, вы создаете необработанный тип Box :

Но если вы назначите необработанный тип параметризованному типу, вы получите предупреждение:

Вы также получите предупреждение, если используете необработанный тип для вызова универсальных методов, определенных в соответствующем универсальном типе:

Предупреждение показывает, что необработанные типы обходят общие проверки типов, откладывая перехват небезопасного кода до времени выполнения. Поэтому вам следует избегать использования необработанных типов.

Раздел Erasure Type содержит больше информации о том, как компилятор Java использует необработанные типы.

Непроверенные сообщения об ошибках

Как упоминалось ранее, при смешивании устаревшего кода с универсальным кодом вы можете столкнуться с предупреждающими сообщениями, подобными следующим:

Примечание: Example.java использует непроверенные или небезопасные операции.

Это может произойти при использовании старого API, который работает с необработанными типами, как показано в следующем примере:

Например, до того как Java-дженерики стали доступны, вы должны использовать класс коллекции следующим образом:

Когда вы добавляете свой объект в список, его не волнует, какой это тип объекта, и когда вы получаете его из списка, вы должны явно привести его к ожидаемому типу.

Используя дженерики, вы удаляете «неизвестный» фактор, потому что вы должны явно указать, какой тип объектов может идти в списке:

Обратите внимание, что при использовании дженериков вам не нужно приводить объект, полученный из вызова get, коллекция предопределена для работы только с MyObject. Этот факт является основным движущим фактором для дженериков. Это превращает источник ошибок времени выполнения во что-то, что можно проверить во время компиляции.

Вы должны указать тип-параметра.

Предупреждение предупреждает, что типы, которые определены для поддержки обобщений, должны быть параметризованы, а не использовать их необработанную форму.

Что такое необработанный тип и почему я часто слышу, что его не следует использовать в новом коде?

«Необработанные типы» используются для обратной совместимости. Их использование в новом коде не рекомендуется, поскольку использование универсального класса с аргументом типа обеспечивает более строгую типизацию, что, в свою очередь, может улучшить понятность кода и привести к более раннему выявлению потенциальных проблем.

Какая альтернатива, если мы не можем использовать необработанные типы, и как это лучше?

Например, для метода, в котором программист хочет убедиться, что переменная List с именем ‘names’ содержит только строки:

Источник

Дженерики в Java для тех, кто постарше: стирание типов, наследование и принцип PECS

Рассказываем, как в любой непонятной ситуации правильно сочетать дженерик-типы.

Что такое стирание и сырые типы raw type необработанный тип. Смотреть фото Что такое стирание и сырые типы raw type необработанный тип. Смотреть картинку Что такое стирание и сырые типы raw type необработанный тип. Картинка про Что такое стирание и сырые типы raw type необработанный тип. Фото Что такое стирание и сырые типы raw type необработанный тип

Что такое стирание и сырые типы raw type необработанный тип. Смотреть фото Что такое стирание и сырые типы raw type необработанный тип. Смотреть картинку Что такое стирание и сырые типы raw type необработанный тип. Картинка про Что такое стирание и сырые типы raw type необработанный тип. Фото Что такое стирание и сырые типы raw type необработанный тип

В предыдущей статье «Дженерики для самых маленьких» мы рассказали о том, что такое дженерики (generics), зачем они нужны и как создавать дженерик-типы и методы. Там же говорили про ограничения (boundings) и wildcards. Без этих основ вам будет сложно разобраться с тем, что написано дальше. Поэтому освежите знания, если это необходимо.

Из этой статьи вы узнаете:

Что такое стирание и сырые типы raw type необработанный тип. Смотреть фото Что такое стирание и сырые типы raw type необработанный тип. Смотреть картинку Что такое стирание и сырые типы raw type необработанный тип. Картинка про Что такое стирание и сырые типы raw type необработанный тип. Фото Что такое стирание и сырые типы raw type необработанный тип

Фулстек-разработчик. Любимый стек: Java + Angular, но в хорошей компании готова писать хоть на языке Ада.

Почему ни один дженерик не доживает до выполнения программы

Воспользуемся примером из первой части рассказа о дженериках: там был класс Box — коробка для сбора мусора: можно было положить в неё или извлечь из неё только объект определённого типа:

Теперь создадим экземпляр такого класса и подставим вместо T конкретный тип: например, Paper — для коробки, в которую будем собирать бумагу:

Можно предположить, что теперь мы имеем дело с таким классом:

Эта запись помогает понять, как класс будет работать, но она не имеет ничего общего с тем, во что превращается дженерик-класс или интерфейс в результате компиляции.

Компилятор не генерирует class-файл для каждого параметризованного типа. Он создаёт один class-файл для дженерик-типа.

Компилятор стирает информацию о типе, заменяя все параметры без ограничений ( unbounded) типом Object, а параметры с границами ( bounded) — на эти границы. Это называется type erasure.

Кроме стирания (иногда говорят «затирания») типов, компилятор может добавлять приведение (cast) к нужному типу и создавать переходные bridge-методы, чтобы сохранить полиморфизм в классах-наследниках.

Пример 1. Стирание типа для дженерика без границ

Все параметры типов заменяются на Object. Вот что получится для нашего класса-коробки:

Пример 2. Стирание типа для дженерика с границами

Объявим дженерик-интерфейс c ограничением сверху ( upper bounding):

Вот что от этого останется после компиляции:

Пример 3. Bridge-метод

Создадим класс-наследник коробки для бумаги и переопределим в нём метод putItem:

Этому классу не всё равно, какого типа объекты приходят к нему в putItem, — нужно, чтобы они были типа Paper. Поэтому компилятору придётся немного докрутить класс — добавить в него bridge-метод с приведением типа:

А вот ещё несколько примеров дженерик-типов и того, что от них останется после компиляции:

До компиляцииПосле компиляции
>Box
Box
List []List[]

Теперь, когда вы знаете про type erasure и его последствия, наверняка сможете ответить на вопрос, почему нельзя создать дженерик-Exception:

В каждом блоке try catch проверяется тип исключения, так как разные типы исключений могут обрабатываться по-разному. Для дженерик-исключения определить конкретный тип было бы невозможно, а потому компилятор даже не даст его создать. Это правило относится к классу Throwable и его наследникам.

Как создать наследника дженерик-класса

Пример 1. Класс-наследник — не дженерик.

Чтобы получить обычный, не дженерик-класс, мы должны вместо параметра T передать какой-то конкретный тип, что мы и сделали — передали Paper.

Пример 2. Класс-наследник и сам дженерик с тем же числом параметров.

Параметры у Box и SuperGenericBox не обязаны обозначаться буквой T (от type) — можно брать любую. В этом примере важно, чтобы буквы были одинаковые, иначе компилятор не разберётся.

Пример 3. Класс-наследник — дженерик с другим числом параметров.

Здесь уже не один, а два параметра. Один передадим родителю, а второй используем как-нибудь ещё — например, напишем метод newMethod с параметром этого нового типа.

У наследника класса-дженерика может быть сколько угодно параметров, включая ноль (когда это вовсе не дженерик). Главное — помнить про все параметры типа родительского класса и передать для каждого параметра конкретный тип или какой-то из параметров класса-наследника.

Что не так с дженерик-типами классов-наследников

В Java можно присвоить объект одного типа объекту другого типа, если типы совместимы: реализуют один и тот же интерфейс или лежат в одной цепочке наследования.

Например, PaperBox — наследник Box, и пример ниже успешно компилируется:

В терминах объектно-ориентированного программирования это называют отношением is a (является): бумажная коробка — это коробка (является коробкой). Или говорят, что PaperBox — это подтип (subtype) Box. При этом Box — супертип PaperBox.

Теперь возьмём не простую коробку, а её дженерик-вариант ( Box ), в которую будем класть разные типы мусора: Paper, Glass и тому подобные типы — наследники Garbage:

В этом случае в качестве аргумента типа можно выбрать как Garbage, так и его подтип:

Но что, если Box станет типом параметра метода? Сможем ли мы в этом случае передать другой дженерик-тип? Напишем простой пример:

И убедимся, что замена тут не пройдёт. Несмотря на то что Paper — подтип Garbage, Box

Дженерики инвариантны. Это означает, что, даже если A — подтип B, дженерик от A не является подтипом дженерика от B.

Для сравнения, массивы в Java ковариантны: если A — подтип B, A[] — подтип B[].

Что такое стирание и сырые типы raw type необработанный тип. Смотреть фото Что такое стирание и сырые типы raw type необработанный тип. Смотреть картинку Что такое стирание и сырые типы raw type необработанный тип. Картинка про Что такое стирание и сырые типы raw type необработанный тип. Фото Что такое стирание и сырые типы raw type необработанный тип

Как переопределить метод с дженерик-типами

Потренируемся сначала на простых типах и вспомним, что при переопределении методов необязательно полностью повторять сигнатуру родительского метода. Например, у таких методов могут различаться типы возвращаемых значений.

Переопределение будет правильным, если тип переопределённого метода — это подтип исходного метода. Например, так:

Добавим немного дженериков и применим то же правило:

Дженерики добавляют ещё пару возможностей для корректного переопределения. Оно будет верным, если:

Звучит сложно, так что лучше взглянем на код:

Правда, в обоих случаях компилятор покажет предупреждение о небезопасном использовании типов ( unchecked warning):

Note: GlassBox.java uses unchecked or unsafe operations.

Его можно понять: исходный метод требует, чтобы возвращался список объектов типа Garbage, а переопределённые хотят просто какой-то список. Там могут быть объекты типа Garbage, а могут и любые другие — вот компилятору и тревожно.

Зато если в исходном методе возвращаемый тип — с wildcard без ограничений, то при аналогичном переопределении предупреждений не будет:

При переопределении дженерик-методов с одинаковым числом параметров типа можно произвольно менять обозначения этих параметров:

В переопределённом методе параметр типа назван S, а не T, но переопределение остаётся корректным.

А вот ограничения для дженерика в переопределённом методе добавлять нельзя:

Получился не переопределённый метод, а просто метод с таким же названием.

Зато можно из дженерик-метода сделать обычный метод:

Компилятор спокоен, потому что метод в классе Box станет именно таким после type erasure — параметр типа будет заменён на Object.

Переопределение дженерик-метода будет корректно, если:

Как wildcards с ограничениями «портят» коллекции и зачем нужен принцип PECS

Если нужно что-то сделать с коллекциями объектов нескольких подтипов, удобны wildcards с ограничениями.

Например: List означает, что список может состоять из объектов типа Paper и всех его подтипов, а в List могут быть объекты типа Paper и всех супертипов — например, Garbage или Object.

С wildcards и коллекциями есть маленькая проблема — коллекции вроде тех, что в примере выше, нельзя использовать на полную катушку: свободно читать из них и записывать новые данные. Чтобы запомнить это ограничение, даже придумали принцип — принцип PECS.

PECS — Producer Extends, Consumer Super. Его суть:

Получается, в коллекцию с extends нельзя добавлять, а из коллекции с super нельзя читать? Вроде бы всё понятно, но давайте проверим:

Попробуем положить сюда экземпляр Paper — наследника Garbage:

Получим ошибку компиляции. Ладно, тогда, может, хотя бы объект типа Garbage подойдёт?

И снова нет. Принцип PECS не соврал — объект в такой список добавить нельзя. Единственное исключение — null. Вот так можно:

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

Добавим туда один объект типа Paper:

И попробуем его же прочитать. Если верить PECS, у нас это не должно получиться:

Но компилятору всё нравится — никаких ошибок нет. Проблемы, впрочем, начнутся, когда мы захотим сохранить полученное значение в переменной типа Paper или типа, совместимого с ним:

Вторая часть принципа PECS означает, что из коллекций, ограниченных снизу, нельзя без явного приведения типа (cast) прочитать объекты граничного класса, да и всех его родителей тоже. Единственное, что доступно, — тип Object:

К сожалению, принцип PECS ничего не говорит о том, какие объекты можно читать из producer, а какие добавлять в customer. Мы не придумали своего принципа, но сделали табличку, чтобы собрать вместе все правила:

Тип ограниченияЧто можно читатьЧто можно записывать
extends SomeType>Объекты SomeType и всех его супертиповТолько null
super SomeType>Объекты типа ObjectОбъекты типа SomeType и всех его подтипов

И даже картинку нарисовали:

Что такое стирание и сырые типы raw type необработанный тип. Смотреть фото Что такое стирание и сырые типы raw type необработанный тип. Смотреть картинку Что такое стирание и сырые типы raw type необработанный тип. Картинка про Что такое стирание и сырые типы raw type необработанный тип. Фото Что такое стирание и сырые типы raw type необработанный тип

Теперь точно не запутаетесь 🙂

Ещё больше хитростей дженериков и других особенностей Java — на курсе «Профессия Java-разработчик». Научим программировать на самом востребованном языке и поможем устроиться на работу.

Источник

Необработанные типы в Java

Почему необработанные типы проблематичны? Узнайте, как и что с этим делать.

1. введение

В этом кратком руководстве мы рассмотрим типы rawtypes, что это такое и почему мы должны их избегать.

2. Необработанные Типы

Необработанный тип – это имя универсального интерфейса или класса без аргумента типа:

Необработанные типы могут быть полезны при взаимодействии с неродовым унаследованным кодом.

В противном случае, однако, это обескураживает. Это потому, что:

3. Невыразительный

Необработанный тип не документирует и объясняет себя так, как это делает параметризованный тип.

Мы можем легко сделать вывод, что параметризованный тип List – это список, содержащий String s. Однако необработанному типу не хватает этой ясности, что затрудняет работу с ним и его методами API.

4. Не Типобезопасно

Давайте посмотрим на это, создав некоторый код, который создает экземпляр List перед передачей его методу, который принимает необработанный тип List и добавляет к нему Целое число :

Компилятор выводит предупреждение из – за использования необработанных типов:

5. Проблемы во время выполнения

Отсутствие безопасности типов в необработанном типе имеет причинно-следственные последствия, которые могут привести к исключениям во время выполнения.

Давайте изменим предыдущий пример так, чтобы method получал элемент в позиции индекса 1 нашего List после вызова Method/|:

6. Заключение

С необработанными типами трудно работать, и они могут привести к ошибкам в нашем коде.

Их использование может привести к катастрофическим последствиям, и, к сожалению, большинство из этих катастроф происходит во время выполнения.

Источник

Стирание типов в Java Объяснено

Узнайте о важном механизме в том, как Java обрабатывает удаление общего типа.

1. Обзор

В этой краткой статье мы обсудим основы важного механизма в универсальных приложениях Java, известного как стирание типов.

2. Что Такое Стирание Типа?

Удаление типов можно объяснить как процесс применения ограничений типа только во время компиляции и удаления информации о типе элемента во время выполнения.

Компилятор заменяет несвязанный тип E фактическим типом Объекта :

Поэтому компилятор обеспечивает типобезопасность нашего кода и предотвращает ошибки во время выполнения.

3. Типы стирания типов

Стирание типов может происходить на уровне классов (или переменных) и методов.

3.1. Стирание типа Класса

Давайте реализуем Стек с использованием массива:

При компиляции компилятор заменяет параметр несвязанного типа E на Объект :

В случае, когда параметр типа E привязан:

Компилятор заменит параметр связанного типа E первым связанным классом, Сопоставимым в этом случае :

3.2. Стирание Типа Метода

Давайте рассмотрим метод отображения содержимого любого заданного массива:

При компиляции компилятор заменяет параметр типа E на Объект :

Для параметра типа связанного метода:

У нас будет параметр типа E удален и заменен на Сопоставимый:

4. Крайние Случаи

Иногда в процессе стирания типов компилятор создает синтетический метод для различения похожих методов. Они могут быть получены из сигнатур методов, расширяющих один и тот же первый связанный класс.

Теперь давайте рассмотрим следующий код:

После стирания типа у нас есть:

Поэтому неудивительно, что попытка вставить строку и присвоить Целое число вызывает исключение ClassCastException из приведения, вставленного во время push компилятором.

4.1. Мостовые методы

Чтобы решить описанный выше пограничный случай, компилятор иногда создает метод моста. Это синтетический метод, созданный компилятором Java при компиляции класса или интерфейса, который расширяет параметризованный класс или реализует параметризованный интерфейс, где сигнатуры методов могут немного отличаться или быть неоднозначными.

В приведенном выше примере компилятор Java сохраняет полиморфизм универсальных типов после удаления, гарантируя отсутствие несоответствия сигнатур метода между Целым стеком s push(Целое число) методом и Стеком s push(объект) методом.

Следовательно, компилятор создает здесь метод моста:

Следовательно, Стек метод класса push после удаления типа делегирует исходный push метод Целочисленного стека класса.

5. Заключение

В этом учебном пособии мы обсудили концепцию стирания типов с примерами в переменных и методах параметров типов.

Вы можете прочитать больше об этих концепциях:

Источник

Что такое сырой тип и почему мы не должны его использовать?

Вопросы:

ОТВЕТЫ

Ответ 1

Что такое необработанный тип?

Спецификация языка Java определяет необработанный тип следующим образом:

JLS 4.8 Необработанные типы

Необработанный тип определяется как один из:

Тип ссылки, который формируется путем принятия имени объявления типового типа без списка аргументов сопутствующего типа.

Тип массива, тип элемента которого является необработанным.

Вот пример, иллюстрирующий:

mt имеет исходный тип (и генерирует предупреждение о компиляции) первой точкой маркера в приведенном выше определении; inn также имеет необработанный тип третьей точкой маркера.

Что такого особенного в сырых типах?

По сути, сырые типы ведут себя так же, как и до появления дженериков. То есть, во время компиляции полностью законно.

Приведенный выше код работает очень хорошо, но предположим, что у вас также есть следующее:

См. также

Как исходный тип отличается от использования как параметры типа?

Ниже приведена цитата из Effective Java 2nd Edition, Item 23: Не используйте raw-типы в новом коде:

Если вы указали appendNewObject на использование параметра raw type List as, то это скомпилируется, и поэтому вы потеряете безопасность типа, которую вы получаете от дженериков.

См. также

Как исходный тип отличается от использования как параметра типа?

Рассмотрим следующий вариант предыдущего фрагмента:

Вернуться к JLS 4.8:

В качестве типа стирания можно использовать тип параметризованного типа или стирание типа массива, тип элемента которого является параметризованным типом. Такой тип называется необработанным.

В более простых выражениях, когда используется тип raw, конструкторы, методы экземпляра и не static также удаляются.

Возьмем следующий пример:

JLS 4.6 продолжает объяснять следующее:

Возвращаемый тип метода и параметры типа общего метода или конструктора также подвергаются стиранию, если подпись метода или конструктора стирается.

Стирание сигнатуры общего метода не имеет параметров типа.

В следующем отчете об ошибке содержатся некоторые мысли от Маурицио Чимадамора, разработчика-компилятора, и Алекс Бакли, одного из авторов JLS, о том, почему должно происходить такое поведение: https://bugs.openjdk.java.net/browse/JDK-6400189. (Короче говоря, это упрощает спецификацию.)

Если это небезопасно, почему разрешено использовать необработанный тип?

Здесь другая цитата из JLS 4.8:

Использование типов raw допускается только как уступка совместимости устаревшего кода. Использование необработанных типов в коде, написанном после введения родословности в язык программирования Java, настоятельно не рекомендуется. Возможно, что будущие версии языка программирования Java будут запрещать использование необработанных типов.

В эффективном Java 2nd Edition также есть следующее:

Учитывая, что вы не должны использовать необработанные типы, почему дизайнеры языка допускают их? Чтобы обеспечить совместимость.

Платформа Java вот-вот вступит в свое второе десятилетие, когда были представлены дженерики, и существовало огромное количество Java-кода, который не использовал дженерики. Было сочтено критически важным, что весь этот код остается законным и совместим с новым кодом, который использует дженерики. Должно быть законным передавать экземпляры параметризованных типов методам, которые были предназначены для использования с обычными типами, и наоборот. Это требование, известное как совместимость с миграцией, приняло решение поддерживать типы raw.

Таким образом, необработанные типы НИКОГДА не должны использоваться в новом коде. Вы всегда должны использовать параметризованные типы.

Нет ли исключений?

К сожалению, поскольку Java-дженерики не переопределены, есть два исключения, в которых необработанные типы должны использоваться в новом коде:

См. также

Ответ 2

Что такое типы raw в Java и почему я часто слышу, что они не должны использоваться в новом коде?

В то время как это работало большую часть времени, произошли ошибки

В старых нетривиальных коллекциях нельзя было обеспечить безопасность типов, поэтому программисту приходилось запоминать то, что он хранил в коллекции.
Генераторы, изобретенные, чтобы обойти это ограничение, разработчик объявит сохраненный тип один раз, и вместо этого компилятор сделает это.

Более сложный интерфейс Compareable:

Обратите внимание, что невозможно реализовать интерфейс CompareAble с compareTo(MyCompareAble) с необработанными типами. Почему вы не должны их использовать:

Что делает компилятор: Дженерики обратно совместимы, они используют одни и те же классы Java, как это делают сырые типы. Магия происходит в основном во время компиляции.

Будет скомпилирован как:

Каковы альтернативы сырым типам: Используйте generics

Ответ 3

Если аргумент фактического типа опущен, вы создаете необработанный тип Box :

Но если вы назначаете необработанный тип параметризованному типу, вы получите предупреждение:

Вы также получаете предупреждение, если используете тип raw для вызова общих методов, определенных в соответствующем родовом типе:

Предупреждение показывает, что проверки типов типов обходного типа обходят общий тип, откладывая улов небезопасного кода на время выполнения. Поэтому вам следует избегать использования необработанных типов.

В разделе «Тип стирания» содержится дополнительная информация о том, как компилятор Java использует необработанные типы.

Непроверенные сообщения об ошибках

Как уже упоминалось ранее, при смешивании устаревшего кода с общим кодом вы можете встретить предупреждающие сообщения, похожие на следующие:

Примечание. Example.java использует непроверенные или небезопасные операции.

Это может произойти при использовании более старого API, который работает с необработанными типами, как показано в следующем примере:

Ответ 4

Вы должны указать параметр типа.

Предупреждение сообщает, что типы, которые определены для поддержки generics, должны быть параметризованы, а не использовать их необработанную форму.

Ответ 5

Например, до того, как были созданы дженерики Java, вы должны использовать класс коллекции следующим образом:

Когда вы добавляете свой объект в список, ему все равно, какой тип объекта он есть, и когда вы его получите из списка, вы должны явно указать его на тот тип, который вы ожидаете.

Используя generics, вы удаляете «неизвестный» коэффициент, потому что вы должны явно указать, какой тип объектов может идти в списке:

Обратите внимание, что с помощью дженериков вам не нужно бросать объект, исходящий из вызова get, сбор предварительно задан для работы с MyObject. Этот факт является основным движущим фактором для генериков. Он меняет источник ошибок времени выполнения во что-то, что можно проверить во время компиляции.

Ответ 6

Компилятор хочет, чтобы вы это записывали:

Ответ 7

Что такое необработанный тип и почему я часто слышу, что их нельзя использовать в новом коде?

«Необработанные типы» используются для обратной совместимости. Их использование в новом коде не рекомендуется, потому что использование универсального класса с аргументом типа позволяет более сильную типизацию, что, в свою очередь, может улучшить понятность кода и привести к появлению потенциальных проблем раньше.

Какая альтернатива, если мы не сможем использовать необработанные типы и как это лучше?

Например, для метода, в котором программист хочет, чтобы переменная List, называемая «имена», содержала только строки:

Ответ 8

Здесь я рассматриваю несколько случаев, через которые вы можете очистить концепцию

Случай 1

Это строгое значение String не Raw Type, поэтому оно никогда не будет вызывать предупреждение.

Случай 2

В этом случае ArrayList arr является строгим типом, но ваш объект new ArrayList(); является сырым типом.

Случай 3

В этом случае ArrayList arr является сырым типом, но ваш Object new ArrayList (); является строгим типом.

Ответ 9

Необработанный тип не должен использоваться, поскольку он может вызвать ошибки времени выполнения, например, вставить double в то, что должно было быть Set int s.

При извлечении материала из Set вы не знаете, что выйдет. Предположим, что вы ожидаете, что это все int s, вы отбрасываете его на Integer ; исключение во время выполнения, когда идет double 3.45.

Ответ 10

Вот еще один случай, когда необработанные типы будут кусать вас:

Как уже упоминалось в принятом ответе, вы теряете всю поддержку обобщений в коде необработанного типа. Каждый параметр типа преобразуется в его стирание (которое в приведенном выше примере является просто Object ).

Ответ 11

Говорят, что ваш list является list объектов, не идентифицированных. Это значит, что Java не знает, какие объекты находятся внутри списка. Затем, когда вы хотите итерировать список, вы должны использовать каждый элемент, чтобы иметь доступ к свойствам этого элемента (в данном случае String).

В общем, это лучшая идея параметризации коллекции, поэтому у вас нет проблем с преобразованием, вы сможете добавлять элементы параметризованного типа, и ваш редактор предложит вам подходящие методы для выбора.

Ответ 12

Чтобы создать параметризованный тип поля, вы указываете фактический аргумент типа для параметра формального типа T:

Если аргумент фактического типа опущен, вы создаете необработанный тип Box:

Ответ 13

Я нашел эту страницу после выполнения некоторых выборочных упражнений и с тем же самым загадкой.

============== Я перешел от этого кода, предоставив образец ================

Это может быть безопаснее, но потребовалось 4 часа, чтобы одурачить философию.

Ответ 14

Сырые типы прекрасны, когда они выражают то, что вы хотите выразить.

Ответ 15

Избегайте необработанных типов

Необработанные типы относятся к использованию универсального типа без указания параметра типа.

Список является необработанным типом, а List является параметризованным типом.

Когда дженерики были представлены в JDK 1.5, необработанные типы были сохранены только для обеспечения обратной совместимости со старыми версиями Java. Хотя использование необработанных типов все еще возможно,

Их следует избегать:

Они менее выразительны и не документируют себя так же, как параметризованные типы. Пример

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *