Skip to the content.

Технологии программирования

Назад на главную

Лекция 2. Базовый синтаксис Java. Тестирование своей программы

Комментарии к коду

Комментарии к коду в Java служат для пояснения кода и для улучшения читаемости кода. Они помогают другим разработчикам понять, что делает код, и как он работает.

Комментарии могут быть однострочными или многострочными. Однострочные комментарии начинаются с двух слешей //, все, что написано после этих символов до конца строки, считается комментарием.

Пример однострочного комментария:

public class Main {
    public static void main(String[] args) {
        int a = 5; // объявляем переменную а
        // вычисляем квадрат числа 5
        int b = a * a;
        System.out.println("Квадрат числа 5 равен: " + b); // выводим результат
    }
}

Многострочные комментарии обычно используются для описания больших блоков кода или для добавления дополнительных пояснений. Они начинаются символами /* и заканчиваются символами */.

Пример многострочного комментария:

public class Main {
    /*
    * Этот метод вычисляет факториал числа. Факториал числа - это произведение
    * всех целых чисел от 1 до этого числа включительно. Например, факториал
    * числа 5 будет равен 120 (1 * 2 * 3 * 4 * 5).
    */
    private static int factorial(int n) {
        if (n == 0)
            return 1;
        else
            return n * factorial(n - 1);
    }
}

Javadoc

JavaDoc - это инструмент для создания документации к Java-коду. Он позволяет создавать подробные HTML-документы с описанием классов, методов, полей и других элементов программы. Это особенно полезно для документирования крупных проектов, чтобы другие разработчики могли быстро разобраться в логике кода.

Чтобы использовать JavaDoc, нужно добавить специальные комментарии к своему коду. Эти комментарии затем преобразуются в HTML-документ.

Вот пример JavaDoc комментариев:

/**
 * Класс для работы с числами Фибоначчи
 * @author Иван Иванов
 * @since 1.0
 */
public class Fibonacci {

    /** 
     * Метод для вычисления n-го числа Фибоначчи. 
     * @param n - номер числа Фибоначчи 
     * @return n-е число Фибоначчи * 
     * @throws IllegalArgumentException, если n < 0 
     * @see FibonacciNumber * 
     * */  
    public int getNthFibonacciNumber(int n) throws IllegalArgumentException {  
        if (n < 0) {  
            throw new IllegalArgumentException("Некорректный номер числа Фибоначчи: " + n);  
        }  
        
        return calculateNthFibonacciNumber(n);  
    }
}

Тип данных char в Java

В Java, char представляет собой символ, который занимает 16 бит памяти и может быть в диапазоне от ‘\u0000’ до ‘\uffff’. Это означает, что char может представлять 65 536 различных символов, включая буквы, цифры и символы в различных кодировках, таких как Unicode.

Объявление char

char c; // Не инициализированный char
char hello = H; // Инициализированный 

Использование char

Ниже приведены некоторые примеры использования char в Java:

char charValue = 'a';
String stringValue = "a";
char symbol = stringValue.charAt(0);
char lastSymbol = stringValue.charAt(stringValue.length() - 1);

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

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

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

Автоматическое приведение типов происходит, когда значение одного типа присваивается переменной другого типа. В этом случае компилятор выполняет неявное преобразование типов, если оно безопасно. Например:

int a = 42;
double b = a;

В этом примере значение ‘42’ автоматически приводится к типу double.

Иногда автоматическое приведение типов может привести к потере информации или вызвать неожиданные результаты. В таких случаях можно использовать явное приведение типов.

Для явного приведения типа используется конструкция (тип) выражение. Например:

double c = 3.14;
float d = (float) c;

Здесь значение ‘c’ явно приводится к типу float.

Массивы в Java

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

тип[] имя_массива = new тип[размер];

где тип - это тип элементов массива, имя_массива - название массива, размер - количество элементов в массиве.

Например, объявим массив целых чисел с именем integers и размером 10:

int[] integers = new int[10];

Доступ к элементам массива осуществляется через индекс, начиная с нуля. Например, для получения значения элемента с индексом 5 нужно использовать следующее выражение:

integers[5]

Двумерные массивы (массивы массивов) в Java объявляются и используются аналогично одномерным массивам, за исключением того, что размер указывается в виде пары индексов, разделенных запятой. Например, объявим двумерный массив целых чисел размером 3x4 (3 строки, 4 столбца):

int[][] matrix = new int[3][4];

Для доступа к элементу с индексом (1, 2) (вторая строка, третий столбец) нужно использовать матрицу следующим образом:

matrix[1][2]

Основные методы массива в Java:

int[] array = new int[5];
System.out.println(array.length); // Выведет 5
double[] original = {1.0, 2.0, 3.0};
double[] copy = original.clone();
System.out.println(Arrays.toString(copy)); // Выведет [1.0, 2.0, 3.0]

Обратите внимание, что клонированный массив содержит ссылку на те же элементы, что и исходный массив, поэтому любые изменения в одном массиве отразятся на другом.

Integer[] numbers = {65, 34, 12, 90};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers)); // Выведет [12, 34, 65, 90]

Примечание: Этот метод изменяет исходный массив, не создавая нового.

String[] words = {"apple", "banana", "cherry"};
System.out.println(words.toString()); // Выведет ["apple", "banana", "cherry"]
byte[] bytes = new byte[100];
Arrays.fill(bytes, (byte)0); // Заполнить массив нулями
Integer[] sortedNumbers = {2, 5, 6, 8, 11, 14, 15};
int target = 10;
int index = Arrays.binarySearch(sortedNumbers, target);
System.out.println("Элемент " + target + " найден в позиции " + index);

Конструкция switch-case

Конструкция switch-case используется в Java для выбора одного из нескольких вариантов выполнения кода. Она работает следующим образом: сначала проверяется условие в операторе switch, затем, в зависимости от результата проверки, выполняется один из блоков case или блок default.

Вот пример использования switch-case:

switch (expression) {
case constant1: // код, выполняемый при значении выражения, равном constant1
                break;
case constant2: // код, выполняемый при значении выражения, равном constant2
                break;
                ...
default:        // код, выполняемый в случае, если ни один из предыдущих случаев не подошел
}

Важно отметить, что выражение в операторе switch должно иметь числовой или строковый тип, либо быть одной из предопределенных констант (например, case 1:). Если выражение имеет ссылочный тип (например, Object), то в switch будет сравниваться адрес объекта в памяти, и выбор варианта будет производиться только если адреса совпадают. Оператор break внутри case обязателен, если его опустить, то выполнение продолжится со следующего варианта case, даже если условие уже выполнилось. Это может привести к ошибкам, поэтому рекомендуется всегда использовать break.

Более современная версия этой конструкции:

String nubmer = "";
switch (i) {
    case 0 -> {
        number = "zero";
        System.out.println(number);
    }
    case 1 -> number = "one";
    case 3 -> number = "three";
    default -> number = "smth other";
}

number = switch (i) {
    case 0 -> printAndReturn("zero");
    case 1 -> "one";
    case 3 -> "three";
    default -> "smth other";
};

Тестирование

Виды тестирования

Что проверять в тестах

Что НЕ проверять в тестах

Другие виды тестирования

Unit тестирование

Что такое unit тест в прикладном смысле?

Программа или функция, которая тестирует какой-то один тест-кейс

Как устроены наши тесты?

Они написаны на groovy. Используется фреймворк spock

Пример теста на groovy

import spock.lang.Specification

class TestSpec extends Specification { 
  
  def "test sum should return false"() {
    /*
    // 1 шаг заводим какие-то данные которые нам нужны
    // 2 шаг делаем действие, которое хотим проверить
    // 3 шаг проверяем результат
    **/
    given:
    def a = 1 // 1 шаг, здесь может быть создание нужных классов
    
    when:
    def sum = a + a // мы вызовем здесь какой-нибудь метод у созданного класса
    
    then:
    // сделать проверку
    // Assert.areEqual() - обычно что-то такое
    // в груви все чуть приятнее - мы можем просто написать boolean выражение
    // и спок будет ждать, что оно должно быть true
    sum == 2
  }
  
  def "test with where"() {
    when:
    def sum = a + b
    
    then:
    sum == sum1
    
    where:
    a  ||  b  ||  sum1
    1  ||  1  ||   2
    2  ||  3  ||   5
    10 ||  1  ||   11
  }
  
}

Материалы для самостоятельного изучения

Ссылка на лекцию в ШБР Яндекса 2022