# Java

## Функция main

```Java
package org.example;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}
```

## Сокращения InteliJ

* psvm - public static void main
* sout - Sytem.out.println()
* serr - System.err.println()
* I - for(Object object: ){}
* fori - for (int i = 0; i< ; i++) {}
* shift + shift - поиск по проекту
* ctrl + alt + t - сниппеты для блоков кода (циклы, if, switch, try-catch)
* alt + insert - сниппеты для класса

## Строки

Строки неизменяемые (immutable) и не могут иметь наследников (final). Для изменения копии

```Java
// foo и bar - 1 объект в Pool (аля static)
String foo = "foo";
String bar = "foo";
// baz - объект в куче
String baz = new String("baz");
```

### StringBuffer и StringBuilder

Данные типы - изменяемые строки с изменениями на месте. StringBuffer синхронизирует методы, поэтому медленее, но можно работать в многопотоке. StringBuilder быстрее, но методы не синхронизирует

```Java
// Можно передать строку в инициализатор, но не обязательно
StringBuffer sb = new StringBuffer(); 

sb.append("foo");
sb.append(5);
```

#### Методы StringBuffer и StringBuilder

* append (смотреть выше)
* delete(int start, int end)
* insert(int offeset, String str)
* replace(int start, int end, String str)
* reverse()
* substring(int start, int end) - создаст новую строку
* toString - перевести в строку

### RegEx

RegEx - щаблон для поиска строки в тексте

#### Примеры RegEx

* "java" - только слово java подойдёт
* "\\d{3}" - 3 цифры

#### Pattern для RegEx

Pattern - скомпилированный RegEx

```Java
Pattern p = Pattern.compile("java");
p = Pattern.compile("java", Pattern.CASE_INSENSETIVE);
```

## Var

Var выбирает тип по типу данных, который мы присваеваем. Нужно инициализировать при объявлении

```Java
var x = 5;
```

## Константы

В Java константы объявляются словом *final*

```Java
final int LIMIT = 5;
```

## Массивы

Объявлять массивы можно разными способами

```Java
int nums[] = new int[] {10, 20};
int[] nums = {10, 20, 30};
```

### Многомерный массив

```Java
int[][] nums = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
```

## Параметры переменной длины

```Java
static void sum(int ...nums) {
    int result = 0;
    for(int n: nums) {
        result += n;
    }
    System.out.println(result);
}
```

Все обязательные параметры до параметрвов переменной длины

## Значения по умолчанию для параметров

**Их нету!!!**

## Перегрузка методов

Перегрузка позволяет определять функции с одинаковым именем, но с разными типами и/или кол-вом параметров.

```Java
static int sum(int a, int b) {
    return a + b;
}

static double sum(double a, double b) {
    return a + b;
}
```

Если отличается только выходной тип, то останется только последняя имплементация

```Java
// Эту версию не получится вызвать
static int sum(int a, int b) {
    return a + b;
}

// Будет вызываться эта версия
static double sum(int a, int b) {
    return a + b;
}
```

## Обработка ошибок

### try-catch-finally

```Java
try {
    int[] a = new int[3];
    a[4] = 5;
} catch (Exception e) {
    e.printStackTrace();
} finally {
    System.out.println("Will always print this");
}
```

### Throw

```Java
throw new Exception("Very important exception! Don't you dare not handle it");
```

### Throws

Позволяет кинуть ошибку вверх по стаку

```Java
public static void main(String[] args) throws Exception {}
```