Выведение типов java-компилятором
Содержание:
- Основные математические функции
- Числовые литералы
- 4 Деление целых и вещественных чисел в Java
- Тригонометрические функции
- Примитивный тип данных (Primitive)
- Конвертация с помощью String.format()
- Символьные типыCharacter types
- Ссылочный тип данных. (Reference)
- Invoking and Instantiating a Generic Type
- 3 Тип String
- Строки и числа
- 2 Причина возникновения шаблонов (коллекции)
- 4 Тип выражения
- Типы Single/Double/Currency
- 2 Расширение типов
Основные математические функции
Java.lang.Math содержит набор базовых математических функций для получения абсолютного значения, наибольшего и наименьшего из двух значений, округления значений, случайных значений и т. д.
Math.abs()
Функция Math.abs() возвращает абсолютное положительное значение переданного ей параметра. Если значение параметра является отрицательным, знак «-» удаляется и возвращается положительное значение, соответствующее отрицательному значению без знака. Вот два примера:
int abs1 = Math.abs(10); // abs1 = 10 int abs2 = Math.abs(-20); // abs2 = 20
Абсолютное значение 10 равно 10. Абсолютное значение -20 равно 20.
Метод Math.abs() представлен в 4 версиях:
Math.abs(int) Math.abs(long) Math.abs(float) Math.abs(double)
Какой из этих методов вызывается, зависит от типа параметра, передаваемого методу Math.abs().
Math.ceil()
Функция округляет значение с плавающей запятой до ближайшего целого числа. Округленное значение возвращается как двойное. Вот пример:
double ceil = Math.ceil(7.343); // ceil = 8.0
После выполнения этого Java-кода переменная ceil будет содержать значение 8.0.
Math.floor()
Функция Math.floor() округляет значение с плавающей запятой до ближайшего целочисленного значения. Округленное значение возвращается как двойное. Вот пример:
double floor = Math.floor(7.343); // floor = 7.0
После выполнения ceil будет содержать значение 8.0.
Math.floorDiv()
Метод Math.floorDiv() делит одно целое число (int или long) на другое и округляет результат до ближайшего целочисленного значения. Если результат положительный, эффект такой же, как при использовании оператора «/» (деления), описанного ранее в этом тексте.
Однако, если результат отрицательный, результат не тот же. С помощью оператора «/» дроби просто усекаются. Для положительных чисел это соответствует округлению в меньшую сторону, для отрицательных — в большую. Метод floorDiv() округляет до ближайшего отрицательного целого числа, вместо того, которое будет происходить при усечении дроби.
Вот пример:
double result3 = Math.floorDiv(-100,9); System.out.println("result3: " + result3); double result4 = -100 / 9; System.out.println("result4: " + result4);
Выходные данные:
result3: -12.0 result4: -11.0
Это показывает разницу между оператором «/» и Math.floorDiv().
Math.min()
Метод Math.min() возвращает наименьшее из двух значений, переданных ему в качестве параметра:
int min = Math.min(10, 20);
После выполнения этого кода переменная min будет содержать значение 10.
Math.max()
Метод Math.max() возвращает наибольшее из двух значений, переданных ему в качестве параметра:
int max = Math.max(10, 20);
После выполнения этого кода переменная max будет содержать значение 20.
Числовые литералы
1.1. Целочисленные литералы
Типы целочисленных литералов в Java:
- десятичные
- восьмеричные
- шестнадцатеричные
- двоичные — начиная с Java 7
Все целочисленные литералы представляют значения int. Если значение литерала лежит в диапазоне , или , то его можно присвоить переменной этого типа без приведения типов. Для создания литерала типа , необходимо явно указать компилятору, дополнив литерал буквой или :
Шестнадцатеричные литералы
- Шестнадцатеричные литералы создаются используя следующие символы
- Должны начинаться с или .
- Разрешается использовать до 16 символов в шестнадцатеричных числах, не учитывая префикс и необязательный суффикс .
Например:
Двоичные литералы в Java 7
Для определения двоичного литерала, добавьте префикс или к числу. Используются числа 0 и 1. Например:
1.2. Литералы с плавающей точкой
Всем литералам с плавающей точкой по умолчанию присваивается тип . Чтобы создать литерал типа , нужно после литерала указать букву или .
Например:
Можно добавить символ или к double литералу, но это не обязательно:
Существует так называемая научная нотация записи вещественных чисел:
Значение этого числа равно .
Может использоваться строчная или прописная буква — , . Также степень может содержать знак + или -. Например:
1.3. Подчеркивание в числовых литералах
Начиная с Java 7, добавлена возможность использовать любое количество символов подчеркивания для разделения групп цифр, что улучшает читабельность.
Подчеркивание может разделять только цифры! Нельзя использовать подчеркивания в следующих местах:
- В начале или конце числа
- Рядом с десятичной точкой в числе с плавающей точкой
- Перед , , или суффиксами
- Для разделения символов префиксов
4 Деление целых и вещественных чисел в Java
При делении целого числа на целое остаток всегда отбрасывается. Как же тогда, скажем, поделить на , чтобы получить ?
Поначалу кажется, что правильный вариант такой:
Однако не все так просто. Дело в том, что Java-машина сначала вычислит значение выражения и только потом присвоит результат в переменную . А деление выполнится нацело. Т.е. будет содержать или, если быть более точным,
Правильный вариант такой: хотя бы одно из чисел, участвующих в делении, нужно записать как вещественное (т.е. с точкой):
В любом из этих выражений будет содержать значение
А как же быть с переменными? Что если у нас есть такой код:
Тут есть хитрое (и очевидное) решение — заставить Java-машину преобразовать переменные в вещественные, умножив их на вещественную единицу —
Обратите внимание, что у операций умножения и деления равный приоритет, и они выполняются слева направо, поэтому имеет значение, где именно мы умножаем на вещественную единицу. Примеры:
Примеры:
Команда | Порядок выполнения | Результат |
---|---|---|
Тригонометрические функции
Класс Java Math содержит набор тригонометрических функций. Эти функции могут вычислять значения, используемые в тригонометрии, такие как синус, косинус, тангенс и т. д.
Mathkpi
Константа Math.PI представляет собой двойное значение, значение которого очень близко к значению PI — математическому определению PI.
Math.sin()
Метод Math.sin() вычисляет значение синуса некоторого значения угла в радианах:
double sin = Math.sin(Math.PI); System.out.println("sin = " + sin);
Math.cos()
Метод Math.cos() вычисляет значение косинуса некоторого значения угла в радианах:
double cos = Math.cos(Math.PI); System.out.println("cos = " + cos);
Math.tan()
Метод Math.tan() вычисляет значение тангенса некоторого значения угла в радианах:
double tan = Math.tan(Math.PI); System.out.println("tan = " + tan);
Math.asin()
Метод Math.asin() вычисляет значение синусоиды значения от 1 до -1:
double asin = Math.asin(1.0); System.out.println("asin = " + asin);
Math.acos()
Метод Math.acos() вычисляет значение арккосинуса от 1 до -1:
double acos = Math.acos(1.0); System.out.println("acos = " + acos);
Math.atan()
Метод Math.atan() вычисляет значение арктангенса для значения от 1 до -1:
double atan = Math.atan(1.0); System.out.println("atan = " + atan);
Вот что говорит JavaDoc:
Если вам нужен этот метод, пожалуйста, прочитайте JavaDoc.
Math.sinh()
Метод Math.sinh() вычисляет значение гиперболического синуса значения между 1 и -1:
double sinh = Math.sinh(1.0); System.out.println("sinh = " + sinh);
Math.cosh()
Метод Math.cosh() вычисляет значение гиперболического косинуса от 1 до -1:
double cosh = Math.cosh(1.0); System.out.println("cosh = " + cosh);
Math.tanh()
Метод Math.tanh() вычисляет значение гиперболического тангенса значения от 1 до -1:
double tanh = Math.tanh(1.0); System.out.println("tanh = " + tanh);
Math.toDegrees()
Метод Math.toDegrees() преобразует угол в радианах в градусы:
double degrees = Math.toDegrees(Math.PI); System.out.println("degrees = " + degrees);
Math.toRadians()
Метод Math.toRadians() преобразует угол в градусах в радианы:
double radians = Math.toRadians(180); System.out.println("radians = " + radians);
Примитивный тип данных (Primitive)
Примитивные типы Java не являются объектами. Всего их восемь, к ним относятся: byte, short, int, long, float, double, charи boolean.
Каждый примитивный тип как член класса имеет значение по умолчанию:
Примитивный тип | Значение по умолчанию |
byte, short, int, long | |
float | 0.0F |
double | 0.0D |
char | 0; или ‘\u0000’ |
boolean | false |
Если использовать локальную переменную без инициализации компилятор выдаст ошибку.
Пример.
В классе объявим несколько полей класса примитивного типа без инициализации, в конструкторе выведем их значения.
public class Test { int x; char ch; boolean f; double d; // конкструтор public Test() { System.out.println("x=" + x); System.out.println("ch=" + ch); System.out.println("f=" + f); System.out.println("d=" + d); } }
Конвертация с помощью String.format()
String.format() — это новый альтернативный метод, который можно использовать для преобразования Integer в объект String. Хотя целью этого метода является форматирование строки, его также можно использовать для преобразования.
Синтаксис
Есть два разных выражения:
public static String format(Locale l, String format, Object… args) public static String format(String format, Object… args)
Параметры
Аргументы для этого метода:
- l: локальный адрес для форматирования;
- format: строка формата, которая включает спецификатор формата и иногда фиксированный текст;
- args: аргументы, которые ссылаются на спецификаторы формата, установленные в параметре format.
Возвращаемое значение
Этот метод возвращает отформатированную строку в соответствии со спецификатором формата и указанными аргументами.
Пример
class Method3 { public static void main(String args[]) { int number = -1234; String str = String.format("%d", number); System.out.println("With format method: string = " + str); } }
Символьные типыCharacter types
Тип является типом символьного представления, который эффективно кодирует члены базовой кодировки выполнения.The type is a character representation type that efficiently encodes members of the basic execution character set. Компилятор C++ обрабатывает переменные типа , и, в отличие от разных типов.The C++ compiler treats variables of type , , and as having different types.
Зависящие от Майкрософт: переменные типа помещаются в тип по умолчанию, если не используется параметр компиляции.Microsoft-specific: Variables of type are promoted to as if from type by default, unless the compilation option is used. В этом случае они рассматриваются как тип и переносятся в без расширения знака.In this case, they’re treated as type and are promoted to without sign extension.
Переменная типа является расширенным символом или типом многобайтового символа.A variable of type is a wide-character or multibyte character type. Используйте префикс перед символьным или строковым литералом, чтобы указать тип расширенных символов.Use the prefix before a character or string literal to specify the wide-character type.
Для конкретного Майкрософт: по умолчанию является собственным типом, но можно использовать для создания определения типа для .Microsoft-specific: By default, is a native type, but you can use to make a typedef for . Тип является синонимом для собственного типа, характерным для Microsoft .The type is a Microsoft-specific synonym for the native type.
Тип используется для символьного представления UTF-8.The type is used for UTF-8 character representation. Он имеет то же представление , что и, но обрабатывается компилятором как отдельный тип.It has the same representation as , but is treated as a distinct type by the compiler. Тип является новым в c++ 20.The type is new in C++20. Для Майкрософт: для использования требуется параметр компилятора.Microsoft-specific: use of requires the compiler option.
Тип используется для символьного представления UTF-16.The type is used for UTF-16 character representation. Он должен быть достаточно большим, чтобы представлять любой блок кода UTF-16.It must be large enough to represent any UTF-16 code unit. Компилятор обрабатывает его как отдельный тип.It’s treated as a distinct type by the compiler.
Тип используется для символьного представления UTF-32.The type is used for UTF-32 character representation. Он должен быть достаточно большим, чтобы представлять любую единицу кода UTF-32.It must be large enough to represent any UTF-32 code unit. Компилятор обрабатывает его как отдельный тип.It’s treated as a distinct type by the compiler.
Ссылочный тип данных. (Reference)
Ссылочным типом называются тип, для которого в ячейке памяти содержится не сами данные, а только адреса этих данных, то есть ссылки на данные.
Ссылочные типы в языке Java включают:
-
- Массивы
- Классы
- Интерфейсы
- Перечисления
Свойства ссылочного типа данных:
Различие примитивных и ссылочных типов данных
Возьмем примитивный тип int и рассмотрим следующий код:
int a=5; // объявляем первую переменную и инициализируем ее int b=a; // объявляем вторую переменную, далее присваиваем b=a. //В этой операции выполняется копирование значения ячейки а в ячейку b a=3; // меняем значение первой переменной // выводим значение переменной a System.out.println(“a= “ + a); // будетвыведено a= 3 // выводим значение переменной b System.out.println(“b= “ + b); // будет выведено b= 5
Из данного примера следует, что при выполнении операции присвоения для переменных, имеющих примитивный тип, выполняется копирование данных из одной ячейки памяти в другую.
Выполним операцию присвоения (копирования) для ссылочных переменных. Для этого напишем простой класс Point -точка на плоскости, имеющая координаты x и y.
public static class Point{ public int x; //координататочки x public inty; //координата тоски y //конструктор Point(int X, int Y) { x=X; y=Y; } }
Создадим несколько объектов класса Point и выполним операцию присвоения.
//cоздаем объект – первую точку //при выполнении данной операции будет //создана переменная объектного типа p1, //которая будет содержать адрес объекта Point p1 = new Point(1,1); //создаем переменную p2 и выполняем //операцию присваивания Point p2=p1; //меняем координату x первого объекта p1.x=7; //выводим координаты первого и второго объекта System.out.println("p1.x="+ p1.x); System.out.println("p1.y="+ p1.y); System.out.println("p2.x="+ p2.x); System.out.println("p3.y="+ p2.y); System.out.println("---------"); //создаем переменную p3 и выполняем Point p3 = null; //создаем третий объект p3= new Point(3,3); //выполняем операцию присваивания //теперь все переменные указывают на //третий объект p2=p3; p1=p3; System.out.println("p3.x="+ p3.x); System.out.println("p3.y="+ p3.y); //выводим коорлинаты System.out.println("---------"); System.out.println("p1.x="+ p1.x); System.out.println("p1.y="+ p1.y); System.out.println("p2.x="+ p2.x); System.out.println("p3.y="+ p2.y); System.out.println("---------");
буудет выведено:
p1.x=7p1.y=1p2.x=7p3.y=1———p3.x=3p3.y=3———p1.x=3p1.y=3p2.x=3p3.y=3———
Из данного примера следует, что при выполнении операции присвоения применительно к ссылочным переменным копируются адреса, а не сами данные. В данном примере мы получили, что все объектные переменные ссылаются на третий объект. Первый объект остался существовать, но на него никто не ссылается. Более того, адрес первого объекта нигде не сохранился, и поэтому это потерянный объект, другими словами «мусор», который только занимает память.
Invoking and Instantiating a Generic Type
To reference the generic Box class from within your code, you must perform a generic type invocation, which replaces T with some concrete value, such as Integer:
Box<Integer> integerBox;
You can think of a generic type invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing a type argument — Integer in this case — to the Box class itself.
Type Parameter and Type Argument Terminology: Many developers use the terms «type parameter» and «type argument» interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type. Therefore, the T in Foo<T> is a type parameter and the String in Foo<String> f is a type argument. This lesson observes this definition when using these terms.
Like any other variable declaration, this code does not actually create a new Box object. It simply declares that integerBox will hold a reference to a «Box of Integer«, which is how Box<Integer> is read.
An invocation of a generic type is generally known as a parameterized type.
To instantiate this class, use the new keyword, as usual, but place <Integer> between the class name and the parenthesis:
Box<Integer> integerBox = new Box<Integer>();
3 Тип String
Тип позволяет хранить текстовые строки.
Чтобы задать какую-то текстовую строку, в Java надо написать текст строки, а с обеих сторон поставить двойные кавычки. Пример:
Код | Пояснение |
---|---|
будет содержать текст | |
будет содержать текст | |
будет содержать текст |
Выглядит несложно, правда? Ну если так, тогда вот еще один интересный факт.
Строки в Java можно склеивать с помощью знака плюс — . Пример:
Код | Пояснение |
---|---|
будет содержать | |
будет содержать пустую строку — вообще без символов. | |
будет содержать |
Обратите внимание на последний пример: мы сложили строку и число. Тут тоже все просто: число будет преобразовано в строку, затем две строки будут склеены
При сложении строк и чисел, всегда получается строка.
Строки и числа
В Java, в дополнение к 8 примитивным типам, типы String и Number (и производные) также должны считаться специальными типами данных (обычно называемыми простыми объектами данных), которые каким-то образом действуют как аналог примитивных данных, где есть необходимость использовать объект, а не тип напрямую (разница станет понятнее в следующих уроках).
На данный момент достаточно знать, что переменные типа String- это последовательности, char которые можно инициализировать с помощью кавычек (двойных кавычек):
String author = «admin»;
В то время как типы Integer, Byte, Long, Float и Double(аналоги тех же примитивных типов, записанные первой строчной буквой) могут быть инициализированы теми же литералами, что и для соответствующих собственных типов, но все они по умолчанию инициализируются литералом null (читать null ), если мы явно не присваиваем им значение.
Компилятор почти всегда может автоматически преобразовывать примитивные типы в соответствующие им простые объекты (операция, называемая упаковкой и распаковкой), только некоторые особые случаи являются исключениями.
2 Причина возникновения шаблонов (коллекции)
Возвращаемся к коллекциям.
Когда Java-разработчики только создавали класс , они хотели сделать его универсальным, чтобы в нем можно было хранить объекты любого типа. Поэтому для хранения элементов они воспользовались массивом типа .
Сильная сторона такого подхода в том, что в коллекцию можно добавить объект любого типа.
Ну а слабых сразу несколько.
Недостаток 1.
Всегда приходилось писать оператор преобразования типа, когда доставали элементы из коллекции:
Код | Примечание |
---|---|
Создаем объект-коллекцию для хранения ссылок на объекты типа Заполняем коллекцию цифрами , , … ; Суммируем элементы коллекцииНужно использовать приведение типа |
Недостаток 2.
Не было гарантии, что в коллекции хранятся элементы определенного типа
Код | Примечание |
---|---|
Создаем объект-коллекцию для хранения ссылок на объекты типа Заполняем коллекцию числами типа :, , , … Суммируем элементы коллекцииБудет ошибка: тип нельзя привести к типу |
Данные в коллекцию могут заполняться где угодно:
- в другом методе
- в другой программе
- загружаться из файла
- получаться по сети
Недостаток 3.
Данные коллекции можно случайно поменять по незнанию.
Вы можете передать коллекцию, заполенную вашими данными в какой-то метод, а этот метод, написанный совсем другим программистом, добавит в вашу коллекцию свои данные.
По названию коллекции непонятно, какие именно типы данных можно в ней хранить. А даже если и дать переменной такое название, ссылку на нее можно передать в десяток методов, и уж там-то точно об изначальном имени переменной ничего не будет известно.
4 Тип выражения
А что делать, если в одном выражении используются переменные разных типов? Логичный ответ – их сначала нужно преобразовать к общему типу. Но какому?
Конечно же, к большему.
В Java всегда происходит преобразование к типу большей размерности. Грубо говоря, сначала происходит расширение типа одного из участников операции, а уже затем операция со значениями одинаковых типов.
Если в выражении участвуют типы и , значение типа будет преобразовано к типу и только затем будет участвовать в операции:
Код | Описание |
---|---|
будет расширена до типа и только затем произойдет сложение. |
Числа с плавающей точкой
Если в выражении участвуют целое число и число с плавающей точкой (/), целое число будет преобразовано в число с плавающей точкой (/), и только потом будет выполнена операция над ними.
Если в операции участвуют и , то будет преобразован к . Что, собственно говоря, ожидаемо.
Сюрприз
Типы , , всегда преобразовываются в тип при взаимодействии между собой. Не зря же тип считается стандартным целочисленным типом.
Если умножить на , будет . Если умножить на , будет . Даже если сложить и , будет .
Тому есть несколько причин. Примеры:
Код | Описание |
---|---|
будет , что несколько больше, чем максимальное значение типа : | |
будет , что тоже несколько больше, чем максимальное значение типа : |
В общем случае при умножении числа длиной в 8 бит (1 байт) на число длиной в 8 бит (1 байт), мы получим число длиной 16 бит (2 байта)
Поэтому все операции с целыми типами, меньшими чем , всегда сразу преобразовываются в тип . И поэтому если вы захотите сохранить результат вычисления в переменную типа, меньше чем , вам всегда нужно будет явно указывать операцию приведения типа.
Примеры:
Код | Описание |
---|---|
выражение будет иметь тип | |
выражение будет иметь тип | |
выражение будет иметь тип единица – это литерал типа . |
Типы Single/Double/Currency
Данные
типа Single и Double содержат числа с плавающей
точкой из разных диапазонов значений.
Single – с 6 верными десятичными разрядами
после запятой, Double – с 14 верными
десятичными разрядами после запятой.
Данные типа Currency также служат для
представления чисел с плавающей точкой,
но число разрядов после запятой ограничено
четырьмя. Этого достаточно при
выполнении денежных расчетов:
Dim
s
As
Single,
a
As
Single
s
=1.7 ‘Результат: 1.7
a
= — 62.697
В
VB в качестве разделителя целой и дробной
частей используется точка.
В
этих инструкциях присваивания справа
от знака равенства находятся константы
с дробной частью. Возможно применение
другого способа записи таких констант.
Этот способ состоит в записи константы
с порядком.
Константы
типа Singleс порядком
выглядят так:
Так |
А |
1.5Е-8 |
1.5*10-8или 0.000000015 |
1E-6 |
0.000001 |
1.256578E5 |
125657.8 |
При
записи констант типа Doubleвместо буквыEприменяется
букваD, что сигнализируетVB, что константа имеет
тип с плавающей точкой, но не обычной,
а двойной точности.
Так |
А |
1.5D-8 |
1.5*10-8или 0.000000015 |
1D-6 |
0.000001 |
1.256578E5 |
125657.8 |
К
числовым переменным можно применять
арифметические операции сложения (+),
вычитания (-), умножения (*), деления (/),
возведения в степень (^) и некоторые
другие, с которыми мы ознакомимся позже.
Тип String
Значением
переменной типа String может быть символ
или строка символов.
Для
того чтобы VB отличал константу типа
строки символов от имени переменной,
константа заключается в парные кавычки:
Dim
Переменная As
String
Переменная
= «Привет Мир» ‘Результат: Привет
Мир
Строки
можно объединять. В качестве оператора
объединения строк в VB можно использовать
как знак суммирования (+), так и знак
«коммерческое и» (&). Однако для
лучшей читаемости кода следует применять
только &, так как знак плюса используется
обычно при суммировании числовых
значений.
Dim
a As String, b As String, c As String
a
= “Петр”
b
= “великий”
c
= a+b
‘Значение: Петр великий
c
= a&b
‘Значение: Петр великий
Тип
Date
Значением
переменной типа Date может быть, дата,
время или дата и время.
Данные
типа Date специально предназначены для
обработки информации о дате и времени.
Чтобы для VB было понятно, что под указанным
значением подразумевается дата и/или
время, нужно поместить его между двумя
знаками #. При вводе следует пользоваться
американским форматом (мм/дд/гг). Если
же при вводе данных этого типа использовать
кавычки («), что допустимо, то следует
применять установленный в системе
формат даты и времени ( как правило –
дд/мм/гг):
Dim
d As Date
d
= #10/16/95# ‘Результат:
16.10.95
d
= #1:25:00 PM# ‘Результат: 13:25:00
d
=
«6.10.95» ‘Результат: 6.10.95
d
= «13:25» ‘Результат: 13:25:00
Тип
Boolean
Переменная
типаBoolean может принимать всего два
значения. Такая переменная может иметь
значениеTrue(истина) или значениеFalse(ложь).
В
VB значению True соответствует 1, а False — 0.
Если переменной этого типа присваивается
значение 0, то переменная содержит False.
Все другие значения подразумевают True:
DimnVarAsBoolean
nVar= 5 ‘Результат:True
Тип
Variant
Универсальный
тип данных Variant — это хамелеон. Он
устанавливает тип данных в зависимости
от содержимого. Если в такой переменной
содержится число, то переменная типа
Variant принимает соответствующий тип
данных.
Если
ее содержимое — число 5, то она принимает
тип Integer;
если
1.2— Double; если текст, то String. Переменная
типа Variant изменяет свой тип во время
выполнения программы. Вот простой
пример:
Dim
V
As
Variant
V
= «25» ‘V содержит «25» (String)
V
= V +5 ‘V содержит 30 (Integer)
V
= V & » штук» ‘V содержит «30 штук»
(String)
Переменные
типа Variant имеют большое практическое
значение, однако, при их применении
возникают проблемы. Во-первых, при чтении
кода не видно, какой внутренний тип
имеет переменная в данный момент. Это
может крайне затруднить обнаружение
логических ошибок программирования.
Во-вторых, данные этого типа занимают
больше памяти, чем аналогичные данные,
объявленные с указанием явного типа.
2 Расширение типов
Часто может возникнуть необходимость присвоить переменной одного числового типа значение переменной другого числового типа. Как же это сделать?
В Java есть 4 целочисленных типа:
Тип | Размер |
---|---|
Переменной большего размера всегда можно присваивать переменные меньшего размера.
Переменной типа спокойно можно присваивать переменные типа , и . Переменной типа можно присваивать переменные типа и . Ну и переменной типа можно присваивать переменные типа .
Примеры:
Код | Описание |
---|---|
Этот код отлично скомпилируется. |
Такое преобразование, от типа меньшего размера к большему, называется расширением типа.
А что насчет вещественных чисел?
С ними все аналогично — размер имеет значение:
Тип | Размер |
---|---|
Переменной типа можно без проблем присвоить переменную типа . А вот с целочисленными типами интереснее.
Переменной типа можно присвоить переменную любого целочисленного типа. Даже типа , длина которого 8 байт. А переменной типа можно присвоить вообще что угодно: переменную любого целочисленного типа и переменную типа :
Код | Примечание |
---|---|
Обратите внимание, что преобразование к вещественному типу может привести к потере точности из-за нехватки значащих цифр. При преобразовании из целых чисел в дробные могут отбрасываться самые младшие части числа
Но т.к. смысл дробного числа в том, чтобы хранить приблизительное значение, такое присваивание разрешается
При преобразовании из целых чисел в дробные могут отбрасываться самые младшие части числа. Но т.к. смысл дробного числа в том, чтобы хранить приблизительное значение, такое присваивание разрешается.