Първа програма на Java

Създаване на проект в IntelliJ IDEA

След стартиране на средата за разработка IntelliJ IDEA се избира опцията New Project, след което се отворя прозорец за конфигурация на новия проект:

image

Попълват се следните основни настройки:

  • Name - име на проекта; в примера от фигурата е JavaBsics
  • Location - директория, в която ще бъде съхранен проектът; в горният пример е Desktop
  • Build System - IntelliJ;
  • JDK - версията на Java, която ще бъде използвана от проекта; в примера от фигурата е OpenJDK-17

Структура на проекта

След създаването на проекта IntelliJ IDEA генерира неговата начална структура.

image

Основните елементи са:

  • Проект - основната директория;
  • src - директория, съдържаща изходния код;
  • out - директория, съдържаща компилираните .class файлове;
  • External Libraries - библиотеките, използвани от проекта.

Забележка: Директорията out се създава автоматично след първото успешно компилиране на проекта.

Организация чрез пакети

Преди създаването на класове е препоръчително първо да бъде създаден пакет.

Пакетите служат за:

  • логическо групиране на класове;
  • избягване на конфликти между имената на класовете;
  • организиране на структурата на пакета.

За създаване на нов пакет върху директорията src от контекстното меню се избира:

New -> Package

В рамките на курса ще бъде използвана следната структура на основния пакет:

bg.tu_varna.sit.<група>.<факултетен_номер>.task<номер_на_задача>

image

Забележка: Предварително дефинираните конвенции за именуване и организация на проектите позволяват различни инструменти автоматично да анализират, компилират, тестват и оценяват програмния код. Поради тази причина и в рамките на курса се използва единна структура на пакетите.

Използване на import

Ключовата дума import се използва, когато в даден файл трябва да се използва клас от друг пакет. Така пълното име на класа не се изписва при всяка употреба.

import java.util.Scanner;

След този запис класът Scanner може да бъде използван само чрез краткото си име.

Scanner scanner = new Scanner(System.in);

Декларациите import се записват след декларацията package и преди декларацията на класа.

package bg.tu_varna.example;

import java.util.Scanner;

public class Application {

}

Създаване на първи клас

След създаването на пакета се създава първия Java клас, като от контекстното меню на пакета се избира New -> Java Class.

Името на класа трябва да бъде смислено и да описва предназначението му. В примерите от курса класът, съдържащ метода main, ще бъде именуван Application.

image

Методът main

Изпълнението на всяко Java приложение започва от метода main:

image

Този метод представлява входната точка на Java приложението. При стартиране на програмата JVM започва изпълнението именно от този метод. В примерите от курса той винаги ще бъде дефиниран в класа Application. Това следва широко използваната практика в Java екосистемата, при която класът, преставляващ входната точка на приложението, се именува по този начин.

Стартирането на методът main може да стане по няколко начина, като фигурата по-долу показва част от тези възможности:

image

Изборът на която и да е от посочените опции ще стартира изпълнението на програмата. Резултатът от конкретния код ще бъде извеждане на конзолата на съобщението (обикновено се отваря в прозорец отдолу):

This is an example

Видове грешки

Грешка в програма е състояние, при което кодът не се компилира, прекъсва изпълнението си или дава резултат, различен от очаквания. Откриването на грешки изисква последователно наблюдение на изпълнението, стойностите на променливите и пътя, по който програмата преминава през условни оператори, цикли и методи.

Синтактична грешка възниква, когато кодът не спазва правилата на езика Java. Такава грешка се открива от компилатора преди стартиране на програмата.

int number = 10
System.out.println(number);

В примера липсва ; след първата инструкция. Програмата не може да бъде компилирана.

Грешка по време на изпълнение възниква след успешно компилиране, когато програмата достигне до операция, която не може да бъде изпълнена.

int result = 10 / 0;

В примера делението на нула води до прекъсване на програмата по време на изпълнение.

Логическа грешка възниква, когато програмата се компилира и изпълнява, но резултатът е неправилен.

int width = 5;
int height = 10;
int perimeter = width * height;

Кодът се изпълнява, но изчислява лице, а не периметър. Такава грешка се открива чрез проверка на стойностите и очаквания резултат.

Debug режим

Debug режимът позволява програмата да се изпълнява контролирано. Вместо да се стартира цялата програма наведнъж, изпълнението може да бъде спирано на избрани редове. Така се наблюдават стойностите на променливите и редът на изпълнение.

Точка на прекъсване се поставя върху ред от програмата. Когато изпълнението достигне този ред, програмата спира временно. След спирането може да се провери текущото състояние на програмата.

int first = 10;
int second = 20;
int sum = first + second;

System.out.println(sum);

Ако точка на прекъсване се постави на реда със sum, може да се види какви стойности имат first и second преди изчислението.

Точки на прекъсване

Точка на прекъсване е маркер върху конкретен ред от програмата. Когато изпълнението достигне този ред в debug режим, програмата спира временно преди изпълнението на инструкцията.

Точка на прекъсване се използва, когато трябва да се провери:

  • дали даден ред от програмата се достига;
  • какви са текущите стойности на променливите;
  • кой клон на условен оператор се изпълнява;
  • колко пъти се изпълнява даден цикъл.
int total = 0;

for (int i = 1; i <= 5; i++) {
    total = total + i;
}

Ако точка на прекъсване се постави в тялото на цикъла, може да се наблюдава как стойностите на i и total се променят при всяка итерация.

Постъпково изпълнение

Постъпковото изпълнение позволява преминаване през програмата ред по ред.

Step Over изпълнява текущия ред и преминава към следващия. Ако текущият ред съдържа извикване на метод, методът се изпълнява без влизане в неговото тяло.

Step Into влиза в извиквания метод. Използва се, когато трябва да се проследи как работи методът отвътре.

Step Out завършва текущия метод и връща изпълнението към мястото, от което методът е извикан.

Пауза, възобновяване и спиране на debugger

Debug изпълнението може да бъде управлявано чрез команди за пауза, възобновяване и спиране.

Pause спира временно изпълняваната програма. Използва се, когато програмата работи дълго или е попаднала в цикъл и трябва да се провери текущото място на изпълнение.

Resume Program продължава изпълнението след спиране на точка на прекъсване. Програмата се изпълнява до следващата точка на прекъсване или до края си.

Stop прекратява debug сесията. След прекратяване програмата вече не се изпълнява под контрола на debugger.

Прозорец за отстраняване на грешки

Прозорецът за отстраняване на грешки показва информация за текущото състояние на програмата, когато изпълнението е спряло. В него се наблюдават текущият метод, стекът на извикванията, стойностите на променливите и изходът на програмата.

Част Предназначение
Debugger Показва управлението на debug сесията и текущото място на изпълнение
Console Показва стандартния изход и съобщенията от програмата
Frames Показва последователността от извикани методи до текущия момент
Variables Показва локални променливи, параметри и полета на достъпните обекти
Watches Позволява наблюдение на избрани изрази по време на debug изпълнение

Стекът във Frames е полезен, когато един метод е извикан от друг метод. Чрез него може да се проследи пътят, по който изпълнението е достигнало до текущия ред.

Прозорец за променливи

При спиране на програмата debugger показва текущите стойности на локалните променливи, параметрите и обектите. Ако дадена променлива сочи към обект, могат да се разгледат и полетата на този обект.

class Student {

    private String name;
    private int facultyNumber;

    public Student(String name, int facultyNumber) {
        this.name = name;
        this.facultyNumber = facultyNumber;
    }
}

При спиране след създаване на обект от Student може да се провери дали полетата name и facultyNumber са инициализирани правилно.

Оценяване на изрази

Оценяването на изрази позволява да се изчисли Java израз по време на debug изпълнение. Изразът се оценява с текущите стойности на променливите.

int price = 50;
int quantity = 3;
int discount = 10;

По време на debug изпълнение може да се оцени израз:

price * quantity - discount

Резултатът е 140. Така може да се провери дали формула, условие или метод връща очакваната стойност.

Quick Evaluate Expression

Quick Evaluate Expression се използва за бърза проверка на избран израз по време на debug изпълнение. Опцията е налична, когато програмата е спряла на точка на прекъсване.

int first = 10;
int second = 20;
int result = first + second;

Ако изпълнението е спряло преди или след изчисляването на result, може да се избере изразът first + second и да се провери неговата стойност. В IntelliJ IDEA това действие може да се изпълни чрез Run -> Debugging Actions -> Quick Evaluate Expression, чрез клавишна комбинация Ctrl+Alt+F8 или чрез Alt и кликване върху избрания израз.

Evaluate Expression

Evaluate Expression позволява оценяване на израз или кратък кодов фрагмент в текущия контекст на изпълнение. Тази операция е по-гъвкава от бързото оценяване, защото може да се въведе нов израз, който не е директно избран от редактора.

int price = 50;
int quantity = 3;
int discount = 10;

При спиране на програмата може да се оцени изразът:

price * quantity - discount

Може да се оцени и условие:

price * quantity > 100

В IntelliJ IDEA действието се отваря чрез Run -> Debugging Actions -> Evaluate Expression или с клавишна комбинация Alt+F8. Оценяването се извършва спрямо текущия стеков кадър, затова могат да се използват само променливи и обекти, които са достъпни на мястото, където програмата е спряла.

Оценяване на условие

Оценяването на изрази е полезно при условни оператори.

int age = 17;

if (age >= 18) {
    System.out.println("Adult");
} else {
    System.out.println("Minor");
}

Ако изпълнението спре преди if, може да се оцени изразът age >= 18. Резултатът показва кой клон на условието ще бъде изпълнен.

Аргументи към main

Методът main може да получава аргументи чрез масива String[] args.

public class Application {

    public static void main(String[] args) {
        System.out.println(args[0]);
    }
}

Ако програмата се стартира без аргументи, достъпът до args[0] води до грешка по време на изпълнение. Debug режимът позволява да се провери дължината на масива чрез args.length и да се установи причината за грешката.


This site uses Just the Docs, a documentation theme for Jekyll.