Почему нельзя создать экземпляр локального класса в Java?

1

Если у меня есть этот код.

public class Test{
        {
            class People {

            }
        }

        public static void main(String[] args) {
            People person = new People();//Compile ERROR
        }

    }

Я не могу создать экземпляр People.

Означает ли это, что блок инициализатора нельзя использовать для определения классов?

Теги:
class
field
local-class

5 ответов

6
Лучший ответ

(Добавив второй ответ, поскольку у меня был неправильный, у него было три upvotes уже.)

Вы можете объявить класс внутри блока инициализатора, но его область действия - это блок инициализатора, как если бы вы объявили его в методе. Итак, это работает:

public class Test {
    {
        class People {            
        }

        People people = new People();
        System.out.println("In initializer block!");
    }

    public static void main(String[] args) {
        new Test();
    }
}

Я не могу сказать, что я когда-либо делал это раньше, и не могу себе представить, что я хочу сделать это в ближайшее время. Обратите внимание, что это локальный класс, который всегда является неявным внутренним классом. (Хотя, если вы объявляете локальный класс в статическом методе, нет закрывающего экземпляра, просто чтобы сделать терминологию немного странной...)

Если вы хотите создать класс, код которого вне блока инициализатора может "видеть", вам нужно объявить его вне блока инициализатора. (Как и любое другое объявление - если вы объявили переменную в блоке инициализатора, вы не ожидали бы, что сможете увидеть ее снаружи?)

  • 0
    Отметим, что объявление класса не может быть static , как вы предлагали ранее и другие ответы.
  • 0
    @ m0skit0: Действительно, это местный класс. (Отсюда, конечно, удаление моего ответа - я сделал ту же ошибку, что и все остальные, но я не хотел, чтобы моя вторая попытка началась с преимуществом +3 голосов :)
Показать ещё 1 комментарий
2

Вы должны сделать внутренний класс static:

static class People {
  • 2
    Здесь есть еще одна проблема: я не думаю, что этот ответ решает: есть дополнительный набор {}, окружающий объявление внутреннего класса. Простое создание статического не компилирует.
  • 2
    Это был и мой первый ответ, но вопрос не в этом.
Показать ещё 2 комментария
1

Ты можешь сделать

Test t = new Test();
People person = t. new People();

Поскольку у людей иначе нет закрывающего экземпляра

РЕДАКТИРОВАТЬ:

Поскольку определение класса находится в блоке инициализации, оно видимо и доступно только локально, INSIDE блок инициализации (что делает его особым местом для определения класса). Класс " People " не может быть видимым в main поскольку для People нет видимого типа. Подход, описанный выше, будет работать только в том случае, если не было блока инициализации вокруг определения класса.

  • 0
    Нет, мы не можем сделать это в основном методе. People - это локальный класс, который относится только к области инициализации блока.
  • 0
    Да, ты можешь. Я просто (повторно) протестировал его, добавив метод в класс People и вызвав его из объекта person в main
Показать ещё 4 комментария
1

Блок инициализатора (определяемый дополнительными скобками) изменяет область действия объявленного класса, поэтому он не будет виден снаружи, как и переменная не будет. Таким образом, единственное место, где может быть создано объект People, находится внутри самого блока, например

{
   class People {
   }

   People person = new People();
}

Без блока инициализации есть два варианта, которым вы можете следовать:

  1. Объявить класс " People " как статический
  2. Создайте объект Test, а затем создайте экземпляр объекта People

В первом случае единственное, что меняется, - это строка

static class People

Во втором случае main метод будет выглядеть примерно так:

public static void main(String[] args) {
    People person = new Test().new People();
}
  • 3
    Дополнительные кронштейны предназначены , чтобы быть там - прочитать последнее предложение вопроса.
  • 0
    Да ты прав. Ответ исправлен. Благодарю.
0

Да, мы можем объявить блок инициализации и область действия класса. Люди будут в нем. Обновите код, как показано ниже:

  public class Test {
    {
        class People {  
             /// Stuff          
        }

        People people = new People(); // Create object of People
        System.out.println("Initializer block");
    }

    public static void main(String[] args) {
        Test obj = new Test();
    }
}
  • 2
    Скобки являются преднамеренными - ФП пытается использовать блок инициализатора в соответствии с последним предложением вопроса.
  • 0
    Да, я пропустил это

Ещё вопросы

Сообщество Overcoder
Наверх
Меню