Java — строго типизированный язык, но передавать значения между примитивными переменными разных типов все же можно. Например, я могу без проблем присвоить значение int двойному значению, если емкость памяти типа, получающего значение, может справиться с этим.
Смотрите ниже размер каждого типа примитива:
Перенос значения в тип с большей емкостью имеет техническое название: «расширяющее преобразование». Этот термин на португальском языке обычно переводится как «преобразование расширения» или «преобразование расширения». Это относится к процессу, в котором значение из меньшего или более ограниченного типа данных преобразуется в более крупный или более полный тип без потери информации.
Но что, если я захочу перенести значение в тип с меньшим объемом памяти? Компилятору 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) { Setset = 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.
Хотя функция удаления в списке заключается в удалении по индексу, функция удаления в наборе заключается в удалении по значению. Все из-за перегрузки команды удаления, получающей целое число.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3