☕ Java

Bedingungen (if/else/switch) in Java 17: Ausführlicher Leitfaden

Переменные и типы данных в Java: полное руководство для начинающих

Любая программа работает с данными: именами, числами, датами, текстами. Для хранения данных используются переменные. В этом уроке изучим все типы данных Java и научимся эффективно с ними работать.

Что такое переменная?

Представьте компьютерную память как огромный склад с ячейками. Каждой ячейке можно дать имя — это переменная. Вместо "возьми данные из ячейки #48293" вы пишете "возьми данные из переменной userName".

Другая аналогия: переменная — это коробка с наклейкой. На наклейке написано имя (score), внутри хранится значение (100). В любой момент можно посмотреть содержимое или заменить его.

Примитивы vs Объекты: два мира Java

Примитивный тип = число прямо на листочке. Хранит само значение. Быстро, компактно.

Объектный тип = конверт с адресом. Переменная хранит ссылку (адрес), а само значение — где-то ещё в памяти.

int age = 25;          // примитив: переменная хранит 25 напрямую
String name = "Иван";  // объект: переменная хранит адрес → объект "Иван"

8 примитивных типов данных

Целые числа (4 типа)

byte  b = 100;              // 1 байт: от -128 до 127
short s = 30_000;           // 2 байта: от -32768 до 32767
int   i = 2_000_000;        // 4 байта: ±2 миллиарда — ИСПОЛЬЗУЙТЕ ПО УМОЛЧАНИЮ!
long  l = 9_000_000_000L;   // 8 байт: очень большие числа, суффикс L обязателен!

// Подчёркивание для читаемости (Java 7+)
int million = 1_000_000;    // Лучше чем 1000000
long trillion = 1_000_000_000_000L;

Правило: Используйте int по умолчанию. long — только для чисел больше ~2 миллиардов.

Числа с плавающей точкой (2 типа)

float  f = 3.14f;     // 4 байта, ~7 знаков точности, суффикс f обязателен!
double d = 3.14159;   // 8 байт, ~15 знаков — ИСПОЛЬЗУЙТЕ ПО УМОЛЧАНИЮ!

Важно! Никогда не используйте float/double для денег:

System.out.println(0.1 + 0.2); // 0.30000000000000004 (!!!)
// Для финансов используйте BigDecimal:
import java.math.BigDecimal;
BigDecimal sum = new BigDecimal("0.1").add(new BigDecimal("0.2"));
System.out.println(sum); // 0.3 точно!

Символ и булев тип

char  c = 'A';         // 2 байта, одиночный символ, ОДИНАРНЫЕ кавычки!
char  tab = '	';      // табуляция
char  newline = '
';  // новая строка
char  uni = 'A';  // Unicode 'A'

boolean flag = true;   // Только два значения: true / false
boolean done = false;
boolean adult = (18 >= 18); // true — результат сравнения

Объявление и инициализация переменных

public class VarDemo {
    public static void main(String[] args) {
        
        // Стиль 1: объявление + инициализация (рекомендуется)
        int score = 100;
        String player = "Алиса";
        boolean active = true;
        double health = 95.5;
        
        // Стиль 2: сначала объявление, потом инициализация
        double temp;
        temp = 36.6;
        
        // Стиль 3: несколько переменных одного типа
        int x = 0, y = 0, z = 0;
        
        // Стиль 4: var — автовывод типа (Java 10+)
        var msg   = "Привет!"; // компилятор видит: String
        var count = 42;        // компилятор видит: int
        var pi    = 3.14159;   // компилятор видит: double
        
        // Изменение значения
        score = 250;
        player = "Боб";
        
        System.out.println("Игрок: " + player + ", очки: " + score);
    }
}

Константы: значения которые не меняются

public class Constants {
    // Константы класса — ЗАГЛАВНЫМИ_БУКВАМИ
    static final double PI     = 3.14159265358979;
    static final int MAX_LIVES = 3;
    static final String APP    = "SuperGame v1.0";
    
    public static void main(String[] args) {
        final int MAX_SCORE = 10_000; // локальная константа
        
        System.out.println("Pi = " + PI);
        System.out.println("Жизней: " + MAX_LIVES);
        
        // MAX_SCORE = 9999; // ОШИБКА: cannot assign a value to final variable
        
        // Встроенные константы:
        System.out.println("Integer.MAX_VALUE = " + Integer.MAX_VALUE); // 2147483647
        System.out.println("Integer.MIN_VALUE = " + Integer.MIN_VALUE); // -2147483648
        System.out.println("Math.PI = " + Math.PI);
        System.out.println("Math.E  = " + Math.E);
    }
}

Преобразование типов (Casting)

Автоматическое расширение (Widening)

// byte → short → int → long → float → double
// Движение "вправо" — Java делает автоматически
int i = 100;
long l = i;      // int → long: автоматически (100L)
double d = i;    // int → double: автоматически (100.0)
System.out.println("int→double: " + d); // 100.0

Явное сужение (Narrowing)

double price = 99.99;
int floor = (int) price;      // Явное приведение
System.out.println(floor);     // 99 (дробь ОТБРАСЫВАЕТСЯ, не округляется!)

// Правильное округление:
int rounded = (int) Math.round(price); // 100

// Ловушка: целочисленное деление
int a = 7, b = 2;
double avg = a / b;            // 3.0 (!!!) — Java делит int/int=3, потом 3→3.0
double correct = (double)a/b;  // 3.5 — правильно!

Тип String: строки в Java

public class StringOps {
    public static void main(String[] args) {
        String name = "Иван Петров";
        
        System.out.println(name.length());           // 11
        System.out.println(name.charAt(0));          // И
        System.out.println(name.substring(5));       // Петров
        System.out.println(name.substring(0, 4));    // Иван
        System.out.println(name.toUpperCase());      // ИВАН ПЕТРОВ
        System.out.println(name.toLowerCase());      // иван петров
        System.out.println(name.contains("Петров")); // true
        System.out.println(name.startsWith("Иван")); // true
        System.out.println(name.indexOf("П"));       // 5
        System.out.println(name.replace("Иван","Алексей")); // Алексей Петров
        System.out.println("  hello  ".trim());      // "hello"
        
        // Разбить строку
        String csv = "яблоко,груша,банан";
        String[] fruits = csv.split(",");
        for (String f : fruits) System.out.println(f);
        
        // Число ↔ строка
        int n = 42;
        String s = String.valueOf(n);      // "42"
        int back = Integer.parseInt("123"); // 123
        double d = Double.parseDouble("3.14"); // 3.14
        
        // ВАЖНО: сравнивать строки через equals(), а НЕ через ==!
        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);      // false (разные объекты!)
        System.out.println(s1.equals(s2)); // true (правильно!)
        System.out.println(s1.equalsIgnoreCase("HELLO")); // true
        
        // StringBuilder — для эффективного построения строк
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 5; i++) {
            sb.append("Строка ").append(i).append("
");
        }
        System.out.println(sb.toString());
    }
}

Wrapper-классы

// Каждому примитиву — класс-обёртка:
// byte→Byte, short→Short, int→Integer, long→Long
// float→Float, double→Double, char→Character, boolean→Boolean

// Autoboxing: примитив → объект автоматически
Integer wrapped = 42;   // int → Integer

// Unboxing: объект → примитив автоматически
int prim = wrapped;     // Integer → int

// Зачем нужны? Нельзя использовать примитивы в коллекциях:
// ArrayList — ОШИБКА!
// ArrayList — правильно!

// Полезные методы
System.out.println(Integer.MAX_VALUE);           // 2147483647
System.out.println(Integer.MIN_VALUE);           // -2147483648
System.out.println(Integer.toBinaryString(42));  // "101010"
System.out.println(Integer.toHexString(255));    // "ff"
System.out.println(Integer.parseInt("100", 2));  // 4 (100 в двоичной = 4)
System.out.println(Double.isNaN(0.0 / 0.0));     // true
System.out.println(Double.isInfinite(1.0/0.0));  // true

Все операторы Java

// Арифметические
int a = 10, b = 3;
System.out.println(a + b);  // 13 — сложение
System.out.println(a - b);  // 7  — вычитание
System.out.println(a * b);  // 30 — умножение
System.out.println(a / b);  // 3  — целочисленное деление
System.out.println(a % b);  // 1  — остаток от деления

// Присваивание
int x = 10;
x += 5;  // x = 15   x -= 3; // 12   x *= 2; // 24   x /= 4; // 6   x %= 4; // 2

// Инкремент/Декремент
int n = 5;
System.out.println(n++); // 5 (вывод ПОТОМ увеличение)
System.out.println(n);   // 6
System.out.println(++n); // 7 (увеличение ПОТОМ вывод)

// Сравнение (результат: boolean)
System.out.println(a == b);  // false    System.out.println(a != b);  // true
System.out.println(a > b);   // true     System.out.println(a < b);   // false
System.out.println(a >= 10); // true     System.out.println(b <= 3);  // true

// Логические
boolean t = true, f = false;
System.out.println(t && f);  // false (И: оба должны быть true)
System.out.println(t || f);  // true  (ИЛИ: хотя бы один true)
System.out.println(!t);      // false (НЕ: инверсия)

Типичные ошибки

// 1. Неинициализированная переменная
int x;
System.out.println(x); // error: variable x might not have been initialized

// 2. Переполнение int
int max = Integer.MAX_VALUE;
System.out.println(max + 1); // -2147483648 — переполнение!
long safe = (long) max + 1;  // 2147483648 — правильно

// 3. Ловушка с целочисленным делением
double result = 5 / 2;         // 2.0, не 2.5!
double correct = (double)5/2;  // 2.5

// 4. Сравнение строк через ==
String s1 = new String("Java");
String s2 = new String("Java");
System.out.println(s1 == s2);     // false (разные объекты)
System.out.println(s1.equals(s2)); // true (правильно!)

// 5. Суффиксы для литералов
long l = 9000000000; // ОШИБКА: нужен суффикс L
long l2 = 9000000000L; // Правильно
float f = 3.14;    // ОШИБКА: 3.14 это double по умолчанию
float f2 = 3.14f;  // Правильно

Итого: что мы узнали

  • ✅ Переменная — именованная ячейка памяти для хранения данных
  • ✅ Примитивы (8 типов): byte, short, int, long, float, double, char, boolean
  • ✅ Используйте int для целых, double для дробных — по умолчанию
  • ✅ final — константа; имена констант ЗАГЛАВНЫМИ_БУКВАМИ
  • ✅ var — автовывод типа компилятором (Java 10+)
  • ✅ Widening (расширение) — автоматически; Narrowing (сужение) — явно (тип)
  • ✅ Для денег — BigDecimal, не float/double!
  • ✅ Строки сравниваем через .equals(), не ==
  • ✅ Wrapper-классы (Integer, Double...) нужны для коллекций