Типы данных, переменные и операторы Java

      Комментарии к записи Типы данных, переменные и операторы Java отключены

Главная Форумы Программирование Учебник по Java Типы данных, переменные и операторы Java

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 1 месяц назад.

  • Автор
    Сообщения
  • #3507
    Предыдущий урок Содержание Следующий урок

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

    Java – это язык со строгой типизацией. Дейст­вительно, часть безопасности и устойчивости к ошибкам Java исходит из этого факта. Во-первых, каждая пере­менная и каждое выражение имеют тип, и каждый тип строго определен. Во-вторых, все назначения – явные, или через передачу параметров в вызо­вах методов, проверяются на совместимость типов. Не имеется никаких ав­томатических приведений или преобразований конфликтующих типов, как в некоторых языках. Компилятор Java проверяет все выражения и парамет­ры, чтобы гарантировать, что типы совместимы. Любые несоответствия ти­пов – ошибки, которые должны быть исправлены прежде, чем компилятор закончит компилировать класс.

    На рисунке показана иерархия типов данных Java:

    Спецификация языка Java, JLS, определяет разрядность (количество байтов, выделяемых для хранения значений типа в оперативной памяти) и диапазон значений каждого типа. Для целых типов они приведены в таблице:

    Тип Разрядность (байт) Диапазон Применение
    byte

    1

    от -128 до 127

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

    short

    2

    от -32768 до 32767

    Этот тип главным образом применим к 16-разрядным компьютерам, которые становятся все более и более редкими.

    int

    4

    от -2147483648 до 2147483647

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

    long

    8

    от -9223372036854775808 до 9223372036854775807

    Тип long64-разрядный тип со знаком. Он полезен в тех случаях, когда тип int недостаточен (по размеру памяти), чтобы хранить желаемое значение. Диапазон значений long весьма велик. Это делает его полезным при работе с большими целыми числами. Например, вот программа, которая

    char

    2

    от '\u0000' до '\uFFFF' , в десятичной форме от 0 до 65535

    Числа с плавающей точкой, также известныe как вещественные числа, ис­пользуются при оценке выражений, которые требуют дробной точности. Например, вычисления квадратного корня или трансцендентных функций типа синуса и косинуса приводят к вещественному значению с определен­ной точностью, что и требует типа с плавающей точкой. Java реализует стандартный (IEEE-754) набор типов с плавающей точкой и соответствую­щие операции с ними. Существует два вида типов с плавающей точкой float и double, которые представляют числа с одинарной и двойной точ­ностью, соответственно. Их ширина и диапазоны представлены в таблице:

    Имя Ширина в битах Диапазон Применение
    double 64 от 1.7е-308 до 1.7е+308 Тип float определяет значение с одинарной точностью, которое использует 32 бита памяти. Вычисления с одинарной точностью быстрее на некоторых процессорах, а значения занимают половину пространства значений двой­ной точности. Но тип оказывается неточным, когда его значения становятся или очень большими, или очень маленькими. Переменные типа float по­лезны, когда нужен дробный компонент, но не требуется большой степени точности. Например, тип float может быть полезен при представлении долларовых цен с учетом центов.
    float 32 от 3.4е-038 до 3.4е+038 Тип двойной точности, обозначаемый ключевым словом double, для хране­ния значений использует 64 бита памяти. На некоторых современных про­цессорах, которые были оптимизированы для высокоскоростных математи­ческих вычислений, операции с двойной точностью на самом деле выпол­няются быстрее, чем с одинарной. Все трансцендентные математические функции, типа sin(), cos() и sqrt(), возвращают double-значения. Когда нужно поддержать точность во многих итерационных вычислениях или ма­нипулировать с многозначными числами, double – лучший выбор.

    Основная форма (формат) объявления переменной выглядит так:

    type identifier [ = value] [, identifier [ = value] . . . ] ;

    Здесь type – один из типов Java, имя класса или интерфейса, identifier – это имя переменной. Можно инициализировать переменную, определяя знак ра­венства (=) и value (в виде литерала подходящего типа). Имейте в виду, что выражение инициализации должно привести к значению того же самого (или совместимого) типа, как и значение, которое определено для перемен­ной. Чтобы объявлять несколько переменных указанного типа, используется список, разделенный запятыми.
    Ниже приведены несколько примеров объявлений переменных различных типов (обратите внимание, что некоторые включают выражения инициализации):

    int a, b, с;                         // три int-переменных a, b и с
    int d = 3, е, f = 5;         // три int-переменных, d и f инициализируются
    byte z = 22;                         // инициализирует z
    double pi = 3.14159;         // аппроксимация ПИ
    char х = 'х';                       // переменная х имеет значение 'х'

    Правила именования переменных

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

    1. меток;
    2. других переменных на данном уровне группирования;
    3. параметров текущего метода.

    Знаки операций с числовыми аргументами

    Знаки операций, аргументами которых являются числа, разделяются на две категории: унарные (unary) знаки операций с одним аргументом и бинарные (binary) – с двумя аргументами. Бинарные знаки операций подразделяются далее на операции с числовым результатом и операции сравнения, результатом которых является булевское значение.

    Результат операции будет всегда принадлежать в тому же типу, что и больший из операндов. Например, если мы складываем два целых числа, одно из которых типа short, а другое типа long, результат будет иметь тип long. Правила выбора типа результата обобщены в таблице (ниже), из которой также следует, что наименьшим результатом, возвращаемым при операциях с целыми числами, является тип int и что при сложении любого числа с числом с плавающей точкой результат будет иметь тип float или double. Теперь перейдем к рассмотрению унарных операций.

    Тип 1 Тип 2 Тип результата
    byte byte int
    byte short int
    byte int int
    byte long long
    short short int
    short int int
    short long long
    int int int
    int long long
    int float float
    int double double
    float float float
    float double double

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

    Операция Результат
    + Сложение (Addition)
    Вычитание (Subtraction) (унарный минус (Unary minus))
    * Умножение
    / Деление (Division)
    % Остаток от деления по модулю (Modulus)
    ++ Инкремент (Increment)
    += Присваивание со сложением (Addition assignment)
    –= Присваивание с вычитанием (Subtraction assignment)
    *= Присваивание с умножением (Multiplication assignment)
    /= Присваивание с делением (Division assignment)
    %= Присваивание с модулем (Modulus assignment)
    –– Декремент (Decrement)

    Таблица операции отношений:

    Операция Результат
    == Равно
    != Не равно
    > Больше чем
    < Меньше чем
    >= Больше чем или равно
    <= Меньше чем или равно

    Таблица операций булевой логики (работают только с операндами типа Boolean)

    Операция Результат
    & Логическое И (Logical AND)
    | Логическое ИЛИ (Logical OR)
    ^ Логическое исключающее ИЛИ (Logical XOR(exclusive OR))
    || Укороченное ИЛИ (Shirt-ciruit OR)
    && Укороченное И (Shirt-ciruit AND)
    ! Логическое унарное отрицание (Logical unary NOT)
    &= Присваивание с И (AND assignment)
    |= Присваивание с ИЛИ (OR assignment)
    ^= Присваивание с исключающим ИЛИ (XOR assignment)
    == Равно (Equal to)
    != Не равно (Not equal to)
    ?: Троичная условная операция (Ternary if-then-else)

    Рассмотрим особенности операции «остаток от деления по модулю», которая представляет собой результат расчета выражения:
    а % b = а - (а / b) * b;
    Например:

    1. 5 % 2 даст в результате 1;
    2. 5 % (-3) даст 2, так как 5 = (-3) * (-1) + 2;
    3. (-5) % 3 даст -2, поскольку -5 = 3 * (-1) - 2.
    4. 50 % 10 = 0.0;
    5. 5 % 10 = 5.0;
    6. 50.5 % 10 = 0.5;
    7. 5.5 % 10 = 5.5;
    8. 0.55 % 10 = 0.55;

    Рассмотрим особенности операции «инкремент (увеличение на единицу)». Оператор:
    х = х + 1;
    можно переписать с помощью операции инкремента так:
    х ++;

    Например:
    х = 4; у = ++х;
    Ответ: y = 5

    Однако:
    х = 4; у = х++;
    Ответ: y = 4.

    Тут значение х присваивается переменной у перед тем, как выполняется опера­ция инкремента, так что значение у равно 4. Конечно, в обоих случаях в х устанавливается значение 5. Здесь строка у = х++; является эквивалентом двух следующих операторов:

    у = х;   
    х = х + 1;

    Операнды арифметических операций должны иметь числовой тип. Их нель­зя применять к переменным типа boolean, но можно использовать на типах char, т. к. тип char в Java, по существу, подмножество int.

    Операция присваивания (назначения) – это одиночный знак равенства (=). Она имеет следующую общую форму:

    var = expression;

    Здесь тип переменной var должен быть совместим с типом выражения ex­pression.
    Различают оператор присваивания = и оператор сравнения ==.

    x = 1; // присваиваем переменной x значение 1
    x == 1 // сравниваем значение переменной x с единицей

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

    int х, у, z;
    х = у = z = 100;      // установить в х, у, и z значение 100

    Этот фрагмент устанавливает в переменных х, у, и z значение 100 с по­мощью одиночной операции присваивания. Это работает, потому что = представляет собой операцию, которая выдает значение правого выражения. Таким образом, значением выражения z = 100 является 100, которое присваи­вается переменной у, а затем, в свою очередь, присваивается переменной х. Использование «цепочки присваиваний» – это просто способ установки общего значения в группе переменных.

    Результат операций отношений – значение типа boolean. Данные любых типов Java включая целые числа, числа с плавающей точкой, символы и булевские переменные, можно сравнивать, используя операции проверки равенства (==) и проверки неравенства (!=). С помощью операций упорядочивания (<, >, <=, >=) можно сравнивать только числовые типы.

    Действия операций булевой логики &, |, и ^ на булевских значениях аналогичны действиям на битах целых чисел. Например, логическая операция отрицания (!) инвертирует булевское значение на противоположное.

    Таблица с эффектами каждой логической операции:

    A B A|B A&B A^B !A
    false false false false false true
    true false true false true false
    false true true false true true
    true true true true false false

    Приоритет операций

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

    Рисунок с приоритетами операций:

    Хотя символы – не целые числа, во многих случаях можно оперировать с ними, как если бы они были таковыми. Это позволяет складывать два символа вместе, или инкрементировать (увеличивать на 1) значение символьной переменной.

    Пример 1. В следующем примере рассматривается оперирование символами как целыми числами:

    Вывод, генерируемый программой:

    chl содержит X
    chl сейчас содержит Y

    В программе переменной chl сначала присваивается значение X. Затем chl инкрементируется. Это приводит к тому, что сh1 будет содержать y – следующий символ в последовательности Unicode.

    Преобразование и приведение типов

    Известно, что довольно обычным делом является присваивание значения одного типа переменной другого типа. Если два типа совместимы, то Java выполнит преобразование автоматически. Например, всегда возможно назначить int-значение long-переменной. Однако не все типы совместимы и, таким образом, не все преобразования типов неявно позволены. Например, не определено никакого преобразования из double в byte. К счастью, все еще возможно осуществить преобразование между несовместимыми типами. Чтобы это сделать, следует использовать специальную операцию приведения типов (cast), которая выполняет явное преобразование между несовместимыми типами. Рассмотрим как автоматические преобразования типов, так и приведение типов.

    Автоматическое преобразование типов в Java

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

    1. два типа совместимы;
    2. целевой тип больше чем исходный.

    Когда эти два условия выполняются, имеет место расширяющее преобразование (widening conversion). Например, тип int всегда достаточно большой, чтобы содержать все допустимые byte-значения, так что никакой явный оператор приведения не требуется.

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

    Приведение несовместимых типов.

    Хотя автоматическое преобразование типов полезно, оно не удовлетворяет всем потребностям. Например, как быть, если вы захотите назначить int-значение byte-переменной? Это преобразование не будет выполнено автоматически, потому что тип byte меньше, чем int. Чтобы создавать преобразование между двумя несовместимыми типами, вы должны использовать приведение типов.

    Для преобразования базовых типов друг к другу применяется операция (тип) — в скобках задается один из совместимых базовых типов. При приведении типов данных меньшей длины к типам большей длины никаких операций производить не требуется. Следует обратить внимание на то, что операция присваивания результатов арифметических операций для примитивных типов char, byte, short вызывает ошибку компиляции, так как при вычислениях производится преобразование к типу int, а Java не позволяет присваивать переменной значение более длинного типа. Исключение составляют операторы инкремента, декремента и операторы +=, -=, *=, /=. Инициализация статических переменных классов и инициализация при объявлении переменных базовых типов в методах разрешается.

    В именах переменных не могут использоваться символы арифметических и логических операторов, а также символ ‘#’. Применение символов ‘$’ и ‘_’ допустимо, в том числе и в первой позиции имени.

    Следующий пример демонстрирует преобразование типов данных и операторы – ошибки, их исправления:

    В результате будет выведено:

    0 res=4
    1 res=-4
    2 res=3
    3 res=6
    4 res=7
    5 res=3
    6 res=6
    7 res=5

    Для приведения объектов к другому типу используются также методы valueOf(), toString() и др. Объекты класса могут быть преобразованы к базовому типу методами intValue(), digit(), longValue() и др.

    В данном примере демонстрируется преобразование типов данных:

    Результатом выполнения данной программы будет:

    s=0.0, s1=10.01
    b=120, b1=120, d=120.0, i=3

    В данном примере используется класс Character – простая оболочка для типа char. Конструктор класса Character имеет следующую форму: Character(char ch), где ch – символ. Чтобы получить char-значение, содержащееся в Character-объекте, вызовите метод charValue(). Сигнатура этого метода: char charValue(). Метод возвращает char-значение, т. е. символ. В Character определены методы forDigit() и digit() со следующим синтаксисом:

    static char forDigit(int num,   int radix) 
    static int digit (char  digit,   int  radix)

    Метод forDigit() возвращает цифровой символ, связанный со значением num. Основание системы счисления преобразования определено в radix. Метод digit() возвращает целое значение, связанное с указанным символом (который, предположительно, является цифрой) с указанным в radix основанием системы счисления.

    Статический метод valueOf(String s) класса Number переопределен для всех подклассов, соответствующих примитивным типам и выполняет действия по преобразованию значения, заданного в виде строки к значению соответствующего объектного типа данных.
    Методы вида byteValue(), intValue() и др., определенные для всех объектных типов, преобразуют значение объектного типа данных к примитивному типу.

Для ответа в этой теме необходимо авторизоваться.