Вопрос-ответ

What causes error "No enclosing instance of type Foo is accessible" and how do I fix it?

Что вызывает ошибку "Нет доступного заключающего экземпляра типа Foo" и как мне это исправить?

У меня есть следующий код:

class Hello {
class Thing {
public int size;

Thing() {
size = 0;
}
}

public static void main(String[] args) {
Thing thing1 = new Thing();
System.out.println("Hello, World!");
}
}

Я знаю, Thing ничего не делает, но моя программа Hello, World отлично компилируется и без этого. У меня сбой только в моих определенных классах.

И он отказывается компилироваться. Я получаю No enclosing instance of type Hello is accessible." строку, которая создает новую вещь. Я предполагаю, что либо:


  1. У меня проблемы системного уровня (либо в DrJava, либо в моей установке Java), либо

  2. У меня есть некоторое базовое непонимание того, как создать рабочую программу на Java.

Есть идеи?

Переведено автоматически
Ответ 1

static class Thing заставит вашу программу работать.

Как это, у вас есть Thing как внутренний класс, который (по определению), связанные с определенным экземпляром Hello (даже если он не использует или ссылается на него), что означает это сообщение об ошибке, чтобы сказать new Thing(); , не имея конкретного Hello экземпляра в объеме.

Если вместо этого вы объявите его как статический класс, то это будет "вложенный" класс, которому не нужен конкретный Hello экземпляр.

Ответ 2

Вы объявили класс Thing как нестатический внутренний класс. Это означает, что он должен быть связан с экземпляром Hello класса.

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

Есть несколько возможных решений. Какое решение использовать, зависит от того, чего вы хотите достичь.


  • Переместиться Thing из Hello класса.


  • Изменить Thing на static вложенный класс.


    static class Thing

  • Создайте экземпляр Hello перед созданием экземпляра Thing.


    public static void main(String[] args)
    {
    Hello h = new Hello();
    Thing thing1 = h.new Thing(); // hope this syntax is right, typing on the fly :P
    }

Последнее решение (нестатический вложенный класс) было бы обязательным, если бы любой экземпляр Thing зависел от экземпляра Hello, чтобы быть значимым. Например, если бы у нас был:

public class Hello {
public int enormous;

public Hello(int n) {
enormous = n;
}

public class Thing {
public int size;

public Thing(int m) {
if (m > enormous)
size = enormous;
else
size = m;
}
}
...
}

любая необработанная попытка создать объект класса Thing, как в:

Thing t = new Thing(31);

было бы проблематично, поскольку не было бы очевидного enormous значения для проверки 31 на соответствие ему. Экземпляр h из Hello внешнего класса необходим для предоставления этого h.enormous значения:

...
Hello h = new Hello(30);
...
Thing t = h.new Thing(31);
...

Потому что это не означает, что Thing если у него нет Hello.

Для получения дополнительной информации о вложенных / внутренних классах: Вложенные классы (руководства по Java)

Ответ 3

Хорошо... так много хороших ответов, но я хочу добавить об этом больше. Краткий обзор внутреннего класса в Java - Java позволяет нам определять класс внутри другого класса, и возможность вложенных классов таким образом имеет определенные преимущества.:


  1. Это может скрывать (это увеличивает инкапсуляцию) класс от других классов - особенно актуально, если класс используется только классом, в котором он содержится. В этом случае внешнему миру нет необходимости знать об этом.


  2. Это может сделать код более обслуживаемым, поскольку классы логически сгруппированы вместе там, где они необходимы.


  3. Внутренний класс имеет доступ к переменным экземпляра и методам содержащего его класса.


В основном у нас есть три типа Inner Classes


  1. Local inner

  2. Статический внутренний класс

  3. Анонимный внутренний класс

Некоторые важные моменты, которые следует запомнить


  • Нам нужен class object для доступа к локальному внутреннему классу, в котором он существует.

  • Прямой доступ к статическому внутреннему классу осуществляется так же, как и к любому другому статическому методу того же класса, в котором он существует.

  • Анонимный внутренний класс не виден внешнему миру, а также другим методам или классам того же класса (в котором он существует), и он используется в точке, где он объявлен.

Давайте попробуем рассмотреть вышеприведенные концепции на практике_

public class MyInnerClass {

public static void main(String args[]) throws InterruptedException {
// direct access to inner class method
new MyInnerClass.StaticInnerClass().staticInnerClassMethod();

// static inner class reference object
StaticInnerClass staticInnerclass = new StaticInnerClass();
staticInnerclass.staticInnerClassMethod();

// access local inner class
LocalInnerClass localInnerClass = new MyInnerClass().new LocalInnerClass();
localInnerClass.localInnerClassMethod();

/*
* Pay attention to the opening curly braces and the fact that there's a
* semicolon at the very end, once the anonymous class is created:
*/

/*
AnonymousClass anonymousClass = new AnonymousClass() {
// your code goes here...

};*/

}

// static inner class
static class StaticInnerClass {
public void staticInnerClassMethod() {
System.out.println("Hay... from Static Inner class!");
}
}

// local inner class
class LocalInnerClass {
public void localInnerClassMethod() {
System.out.println("Hay... from local Inner class!");
}
}

}

Я надеюсь, что это поможет всем. Пожалуйста, обратитесь за дополнительной информацией

Ответ 4

Thing это внутренний класс с автоматическим подключением к экземпляру Hello. Вы получаете ошибку компиляции, потому что нет экземпляра Hello, к которому он мог бы подключиться. Вы можете исправить это проще всего, изменив его на статический вложенный класс, к которому нет подключения:

static class Thing
java