Страницы

Поиск по вопросам

понедельник, 2 декабря 2019 г.

Принцип восприятия фигурных скобок в Java

#java


Не знаю можно ли назвать вопрос риторическим, но вот в чем суть. Может кто пояснить
все тонкости с связанные с фигурными скобками - {}(если таковые конечно есть)

Я имею представление о том, что if, for, методы, классы и прочие вещи используют
фигурные скобки как бы для определения своего поля влияния, и по сути, когда мы пишем
if { // код }, мы обозначаем, что данный блок будет предназначаться расположенному
с ним if'у.

Меня интересует, есть ли какие-либо особенности блоков, не имеющих такой привязки?

К примеру, я не могу вне метода написать sysout("bla"); (то есть, прямо внутри класса),
но когда заключаю оператор в блок {} проблема исчезает - магия.
Почему так?

Где-то видел насчет этого какую-то информацию о том, что есть, к примеру, в классах
некие статические блоки инициализации и прочее, типа:

static {
    // Чудо-код
} 
Заранее благодарю;


// Или может еще как то так...


Почему тут ругает:

public class Main {

    System.out.println("a");

    public static void main(String[] args) {

    }
}


а тут нет

public class Main {

    {    
        System.out.println("a");
    }

    public static void main(String[] args) {

    }

}


Код в блоке воспринимается как что? В чем разительные отличия?
    


Ответы

Ответ 1



Структура класса в Java может включать в себя блок инициализации полей, блок статической инициализации, блок нестатической инициализации для объекта класса, методы и конструкторы класса (как частный случай методов). Синтаксисом языка принято, что область действия каждого оператора (начало и конец) должна быть обозначена фигурными скобками. Верхний уровень, как правило, обозначается оператором class и его область действия может включать инициализацию полей, блок статической и нестатической инициализации, конструкторы и методы. Границы (начало и конец) конструкторов, методов и блоков инициализации так же обязаны быть обозначены фигурными скобками. Кроме того, фигурными скобками может быть объединено несколько операторов в отдельный исполняемый блок (включая и один оператор, как это ни странно :)). Исполняемый код в этой структуре может находится только в теле метода (конструктора, как частный случай метода) или блоке статической (нестатической для объекта) инициализации и запущен на исполнение по имени этого метода (в случае блока статической (нестатической) инициализации - в момент создания класса). Таким образом в структуре вида: public class Program { { System.out.println("a"); } } Мы определяем блок нестатической инициализации. Вывод значения "a" будет выполнено при каждом создании этого экземпляра класса (объекта). public class Main { public static void main(String[] args) { Program p = new Program(); } } Выведет "а" на консоль. Стоит учесть, что если определить блок нестатической инициализации в классе входа в программу (который содержит метод main()), то данный блок выполнен не будет, поскольку экземпляр этого класса не создается и данный блок должен быть определен, как static. Если фигурные скобки опустить, то возникает ошибка, поскольку в структуре класса, без отдельного выделения в блок кода фигурными скобками, может производиться только инициализация полей класса: public class Program { int SomeValue; } Подробнее про виды инициализации в классе. Ну и ответ на ваш вопрос: В первом случае получается синтаксическая ошибка, так как операторы языка не могут существовать вне блока кода, определенного фигурными скобками, во втором случае вы определяете блок нестатической инициализации. Здесь нет никакой магии.

Ответ 2



В фигурные скобки помещаются: Тело интерфейса или класса: interface MyInterface { //Тело интерфейса } class MyClass { //Тело класса } Тело метода: public void myMethod(...) { //Тело метода } Тело условного оператора: if(...) { //Тело условного оператора "if" } switch (...) { case 1: //... break; case 2: //... break; default: //... break; } Тело цикла: for(int i=0; i<10; i++) { //Тело цикла "for" } while(...) { //Тело цикла "while" } do { //Тело цикла "do ... while" } while (...); Набор элементов для инициализации массива: int[] myArr = {0, 2, 4, 6, 8}; Блок статической инициализации (выполняется при первой загрузке класса): class MyClass { static { //Блок статической инициализации } } Блок НЕстатической инициализации (выполняется после отработки любого конструктора данного класса): class MyClass { { //Блок НЕстатической инициализации } }

Комментариев нет:

Отправить комментарий