«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Уход за переносом типов в Java

Уход за переносом типов в Java

Опубликовано 8 ноября 2024 г.
Просматривать:631

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

Смотрите ниже размер каждого типа примитива:

Cuidados com transferência de tipos em Java

Перенос значения в тип с большей емкостью имеет техническое название: «расширяющее преобразование». Этот термин на португальском языке обычно переводится как «преобразование расширения» или «преобразование расширения». Это относится к процессу, в котором значение из меньшего или более ограниченного типа данных преобразуется в более крупный или более полный тип без потери информации.

Но что, если я захочу перенести значение в тип с меньшим объемом памяти? Компилятору Java это не нравится, но он позволит это сделать, если вы его приведете, как в примере ниже.

double decimal = 65.9;
int i = (int) decimal; //aqui ele perde a casa decimal e vira 65
char c = (char) i; //aqui ele vira a letra A (que corresponde a 65)

Если размер значения, которое будет передано в новый тип, превышает пределы этого типа, может произойти нечто более драматичное. Int i = 10 подходит для байтовой переменной, так как содержит 8 бит в диапазоне от -128 до 127. Однако что, если я захочу поместить int i = 128 в переменную типа byte... будет потеря информации .

public class Main
{
    public static void main(String[] args) {
        int i = 128;
        byte b = (byte) i;

        System.out.println(b); // o valor de b agora é -128 :S
    }
}

Автобокс

В последнем посте [читайте его здесь] я немного рассказал о классах Wrapper. В качестве примера я написал Integer.parse(i) = представьте, что i — это тип
примитивный инт.

В настоящее время использование метода анализа Wrapper больше не рекомендуется, поскольку он устарел. Чтобы преобразовать примитив в класс Wrapper и таким образом использовать встроенные методы, рекомендуется делать «автобоксинг», как в примере:

Character ch = 'a';
Integer i = 10;

Обратите внимание, что это более прямой подход. Вы просто присваиваете значение сразу.

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

Integer i = 10;
int j = Integer.valueOf(i);

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

Версия примитива-оболочки на первый взгляд может выглядеть очень похожей, но не забывайте, что JVM не относится к объекту и примитиву одинаково. Помните, что примитивы помещаются в стек, а объекты — в кучу [помните здесь].

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

Но бывают случаи, когда использование Wrapper будет необходимо. Например, если вы хотите работать с классом ArrayList. Он принимает в качестве параметров только объекты, а не примитивные значения.

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

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

Этот случай был упомянут в книге Джошуа Блоха «Эффективная Java».

public class SetListTest {
    public static void main(String[] args) {
        Set set = new TreeSet();
        List list = new ArrayList();

        for (int i = -3; i 



В этой программе целью было добавить целые значения от -3 до 2 [-3, -2, -1, 0, 1, 2] в набор и список. Затем удалите положительные значения [0, 1 и 2]. Но если вы запустите этот код, вы заметите, что набор и список не дали одинаковый результат. Набор возвращает [-3, -2, -1], как и ожидалось. Список возвращает [-2, 0, 2].

Это происходит потому, что вызов встроенного метода удаления(i) класса List рассматривает i как примитивный тип int и ничего больше. Метод, в свою очередь, удаляет элементы в позиции i.

Вызов метода удаления(i) класса Set вызывает перегрузку, которая получает объект Integer в качестве параметра, автоматически преобразуя i, которое изначально было int, в Integer. Поведение этого метода, в свою очередь, исключает из набора элементы, имеющие значение, равное i (а не индекс, равный i) — обратите внимание, что ожидаемым типом как для набора, так и для списка был Integer. (Установить набор/Список списка). Вот почему перегрузка, выбранная для метода удаления класса Set, преобразовала его в Integer.

Хотя функция удаления в списке заключается в удалении по индексу, функция удаления в наборе заключается в удалении по значению. Все из-за перегрузки команды удаления, получающей целое число.

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/anaccortez/cuidados-com-transferencia-de-tipos-em-java-10he?1 Если есть какие-либо нарушения, пожалуйста, свяжитесь с [email protected], чтобы удалить ее.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3