Лекция 2

Типы данных

Тип данных — это множество значений и возможных операций над ними. В Java есть 8 базовых типов и бесконечно много объектных типов, их можно создавать самостоятельно и их уже много определено в станадартной библиотеке.

8 базовых:

Пример объектного типа — это String (строки), другие примеры: File, Scanner, Date, …

Целые типы:

byte - 1 байт, short — 2 байта, int - 4, long - 8.

Все целые типы знаковые, это значит, что в них можно хранить и отрицательные, и пложительные числа. в byte можно сохранить от -128 до 127. В short ~-32000 до +32000. В int от -2млрд до +2 млрд, в long много, порядка 10^18.

Если мы в программе пишем число, например, 12, имеется в виду значение типа int. Вообще, int основной тип, и другие нужны редко. Например, даже 3000000000 — нельзя, потому что 3 миллиарда не помещается в int.

Как записывать числа — отдельный раздел, он называется

литералы целых чисел

литерал — последовательность символов в программе, которая означает значение некоторого типа. Например, 123 — литерал целого числа int, если пишете, “abc” — литерал типа String.

Число записывается цифрами, это число в 10-ой системе счисления, и если нужна 8-ая система счисления, в начале ставится 0, если 16-ая, то 0x:

a = 123  // 10-ая система счисления
b = 0123 // 8-ая система счисления
с = 0x123 // 16-ая система счисления
color = 0xFF0000 // красный

a = 42      // обе записи эквивалентны
a = 0x2A

Можно в числа вставлять подчеркивания:

a = 1000000000          //эквивалентно
a = 1_000_000_000

Если нужно значение типа long, в конце пишется L:

x = 3_000_000_000L  // нормально, тип long

Операции над целыми числами:

+ - * / % (остаток от деления):

деление для целых чисел работает как целочисленное деление. Например, 6 / 3, получается число 2 типа int. Т.к. мы делим int на int. А если 7 / 3, это тоже значение типа int. Будет 2, дробная часть отброшена. (В python это операция // ).

Пример про остаток, 7 % 3 получается 1.

Дробные типы, литералы, операции

double и float.

double - более точный, чем float.

По-умолчанию дробное число считается, что имеет тип double, чтобы записать число типа float, в конце нужно приписывать F. Примеры литералов:

2.      //это и далее: double
2.0
2.5
2.38
-1.33
-0.55
-0.55F   // типа float
3.45e2  //e2 означает умножение на 10^2
345.  // эквивалентно предыдущему
1E9  //миллиард
1E-9 //одна миллиардная

Операции над вещественными: + - * /, но для вещественных чисел деление тоже вещественное.

2 / 3         // 0 int на int
2. / 3.       // 0.666666 double на double

Будьте внимательны с вычислениями с вещественными числами, потому что они неправильные. 0.1 + 0.2 это 0.30000000000000004.

Неявное приведение типов

В Java у каждого выражения точно известен тип, еще на этапе написания программы: 2 + 2 * 6.5, 6.5 это double, 2 это int. Какой тип у 2 * 6.5? Операция * может работать только для элементов одного типа. Либо int на int, либо double на double, либо short на short и т.д. Поэтому нужно преобразовывать тип. И Java добавляет неявную (невидимую) операцию, которая превращает 2 типа int в 2.0 типа double. Поэтому 2 * 6.5 имеет тип double. После этого вычисляется 2 + 2*6.5, и первая двойка тоже неявно преобразуется в double, поэтому всё выражение имеет тип double.

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

Особый случай, иногда char (символ) превращается в int. 'a' + 1 — это число int.

Тип boolean

Всего два литерала (два значения): true и false (с маленькой буквы).

Операции: && — логическое и, || — логическое или, ^ — исключающее или, ! — просто отрицание.

true || false   -> true
false && false -> false
!true -> false
!false -> true

Не используйте & и | (одинарные).

Пример, когда & все испортит:

if (x != 0 && y / x > 2) ...

Если x = 0, то первое выражение уже false, второе выражение вычисляться не будет. А вот если использовать &, то Java всё равно вычислит вторую половину выражения y/x, и возникнет ошибка деления на 0.

Операции сравнения

Операции работают со значениями разных типов, но возвращают логический тип: == равно объектов, ! = неравно , < =, > =, <, >.

Первые две операции можно использовать для значений вообще любых типов. А последние 4 — только с числовыми типами. Результат вычисления будет логический:

2 > 3  // false
3 > 2  // true
10 >= 20 // false
"abc" == "abc" // ?? потом обсудим сравнение строк

Символьный тип char.

Хранит символы стандарта Unicode. Литералы записываются через одинарную кавычку:

'a' - символ буква а
'b' - буква бэ
'#' - символ диеза
'*' - символ звездочка, умножения
' ' - пробел
'щ' - буква ща, вводится в русской раскладке
'ξ' - греческая буква кси

Иногда хочется написать символ, зная его код, тогда пишется \u в начале, потом код

'\u03BE' - это та же самая греческая кси

Кроме этого, есть много других символов, которые можно ввести с помощью обратного слеша:

'\n' - перевод строки
`\\` - символ слеша

Тип String

Не базовый тип, объектный. Литералы — это несколько символов подряд, записанных в двойных кавычках:

"abc" - строка из трех символов
"abc\n" - строка из четырех символов
"\u03BE\u03BE" - строка из двух символов.
"\u03BE \u03BE" - строка из трех символов.  

В последних Java появились другие литералы строк.

Операция над строками: есть конкатенация, + складывает строки.

Пример:

"abc" + "xyz"  -> "abcxyz"
"abc" + 2 -> 2 автоматом превратится в строку
             "abc2"
2 + "abc" -> "2abc"
1 + 2 + "abc" -> "3abc"
1 + (2 + "abc") -> "12abc"

Шаблон программы

class Task1 {
    public static void main(String[] args) {
        int x = 42; //x типа int
        double y = 42.0; //y типа double
        String s = ""; //s строка
        if (x > 10) {
            System.out.println("больше 10");
        } else {
           if (x < 0) {
               System.out.println("меньше 0");
           }
        }
        
        //значение из переменной x превратится
        //в строку
        System.out.println("x = " + x);
    }
}