что такое стирание и сырые типы raw type необработанный тип
Стирание типов в Java
Отрывок с книги по которому есть пару вопросов:
«Обычно подробно знать, каким образом компилятор Java преобразует исходный текст программы в объектный код, нс нужно. Но что касается обобщений, то некоторое общее представление об этом процессе все же следует иметь, поскольку оно объясняет принцип действия механизма обобщений, а также причины, по которым он иногда ведет себя не совсем обычно. Поэтому ниже описывается вкратце, каким образом обобщения реализованы в языке java. Важное ограничение, которое было наложено на способ реализации обобще11ий в Java, состояло в том, что требовалось обеспечить совместимость с предыдущими версиями Java. Проще говоря, обобщенный код должен быть совместим с прежним кодом, существовавшим до появления обобщений. Это означает, что любые изменения в синтаксисе языка Java или виртуальной машине JVМ должны вноситься, не нарушая старый код. Способ, которым обобщения реализуются в Java для удовлетворения этому требованию, называется стиранием. Рассмотрим в общих чертах принцип действия стирания. При компиляции прикладного кодаjаvа все сведения об обобщенных типах удаляются (стираются). Это означает, что параметры типа сначала заменяются их ограничивающим типом, которым является тип Object, если никакого явного ограничения не указано. Затем выполняется требуемое приведение типов, определяемое аргументами типа, для обеспечения совместимости с типами, указанными в этих ар1-уменпtх. Компилятор также обеспечивает эту совместимость типов. Такой подход к обоб* щениям означает, что никаких сведений о типах во время выполнения не суще* ствует. Это просто механизм автоматической обработки исходного кода.»
Преобразование типов в JAVA
Добрый вечер. Мне нужна помощь с преобразованием типов. У меня такой вопрос: можно ли.
Размеры типов в Java
Здравствуйте, киберчане. Как все мы знаем в Java существует 8 примитивных типов данных и.
Расширение типов в java
Итак есть такой код long a =0x1_0000_0000L+ 0xCAFE_BABE; System.out.println(a ==.
Представление целочисленных типов в Java
Здравствуйте. Не могу понять написанное в книге: Проясните, пожалуйста, написанное.
Что такое сырой тип и почему мы не должны его использовать?
Вопросы:
ОТВЕТЫ
Ответ 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. Хотя использование необработанных типов все еще возможно,
Их следует избегать:
Они менее выразительны и не документируют себя так же, как параметризованные типы. Пример
Что такое сырой тип и почему мы не должны его использовать?
Вопросы:
ОТВЕТЫ
Ответ 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. Хотя использование необработанных типов все еще возможно,
Их следует избегать:
Они менее выразительны и не документируют себя так же, как параметризованные типы. Пример
Необработанные типы в Java
Почему необработанные типы проблематичны? Узнайте, как и что с этим делать.
1. введение
В этом кратком руководстве мы рассмотрим типы rawtypes, что это такое и почему мы должны их избегать.
2. Необработанные Типы
Необработанный тип – это имя универсального интерфейса или класса без аргумента типа:
Необработанные типы могут быть полезны при взаимодействии с неродовым унаследованным кодом.
В противном случае, однако, это обескураживает. Это потому, что:
3. Невыразительный
Необработанный тип не документирует и объясняет себя так, как это делает параметризованный тип.
Мы можем легко сделать вывод, что параметризованный тип List – это список, содержащий String s. Однако необработанному типу не хватает этой ясности, что затрудняет работу с ним и его методами API.
4. Не Типобезопасно
Давайте посмотрим на это, создав некоторый код, который создает экземпляр List перед передачей его методу, который принимает необработанный тип List и добавляет к нему Целое число :
Компилятор выводит предупреждение из – за использования необработанных типов:
5. Проблемы во время выполнения
Отсутствие безопасности типов в необработанном типе имеет причинно-следственные последствия, которые могут привести к исключениям во время выполнения.
Давайте изменим предыдущий пример так, чтобы method получал элемент в позиции индекса 1 нашего List после вызова Method/|:
6. Заключение
С необработанными типами трудно работать, и они могут привести к ошибкам в нашем коде.
Их использование может привести к катастрофическим последствиям, и, к сожалению, большинство из этих катастроф происходит во время выполнения.