Что вызывает ошибку "Нет доступного заключающего экземпляра типа 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."
строку, которая создает новую вещь. Я предполагаю, что либо:
- У меня проблемы системного уровня (либо в DrJava, либо в моей установке Java), либо
- У меня есть некоторое базовое непонимание того, как создать рабочую программу на 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 позволяет нам определять класс внутри другого класса, и возможность вложенных классов таким образом имеет определенные преимущества.:
Это может скрывать (это увеличивает инкапсуляцию) класс от других классов - особенно актуально, если класс используется только классом, в котором он содержится. В этом случае внешнему миру нет необходимости знать об этом.
Это может сделать код более обслуживаемым, поскольку классы логически сгруппированы вместе там, где они необходимы.
Внутренний класс имеет доступ к переменным экземпляра и методам содержащего его класса.
В основном у нас есть три типа Inner Classes
- Local inner
- Статический внутренний класс
- Анонимный внутренний класс
Некоторые важные моменты, которые следует запомнить
- Нам нужен 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