是啥导致错误“无法访问 Foo 类型的封闭实例”,我该如何解决?
Posted
技术标签:
【中文标题】是啥导致错误“无法访问 Foo 类型的封闭实例”,我该如何解决?【英文标题】:What causes error "No enclosing instance of type Foo is accessible" and how do I fix it?是什么导致错误“无法访问 Foo 类型的封闭实例”,我该如何解决? 【发布时间】:2012-03-22 13:37:48 【问题描述】:我有以下代码:
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 中构建工作程序有一些基本的误解。
有什么想法吗?
【问题讨论】:
Java inner class and static nested class 的可能重复项 【参考方案1】:Thing
是一个inner class,自动连接到Hello
的实例。你会得到一个编译错误,因为没有Hello
的实例可以附加到它。您可以通过将其更改为没有连接的static nested class 来最轻松地修复它:
static class Thing
【讨论】:
【参考方案2】:static class Thing
将使您的程序正常运行。
事实上,您将Thing
作为一个内部类,它(根据定义)与Hello
的特定实例相关联(即使它从未使用或引用它),这意味着它是一个错误地说 new Thing();
而没有特定的 Hello
实例在范围内。
如果您将其声明为静态类,则它是一个“嵌套”类,不需要特定的 Hello
实例。
【讨论】:
这是否也意味着如果我实例化outer class
,即使我没有在任何地方使用它也会创建non-static inner class
?
没有。内部类的每个对象都必须有父对象,但父对象可以有任意数量的子对象,包括 0。【参考方案3】:
您已将类 Thing
声明为非静态内部类。这意味着它必须与Hello
类的实例相关联。
在您的代码中,您尝试从静态上下文创建Thing
的实例。这就是编译器所抱怨的。
有几种可能的解决方案。使用哪种解决方案取决于您想要实现的目标。
将Thing
移出Hello
类。
将Thing
更改为static
嵌套类。
static class Thing
在创建Thing
的实例之前创建Hello
的一个实例。
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 。 Hello
外部类的实例 h
是提供此 h.enormous
值所必需的:
...
Hello h = new Hello(30);
...
Thing t = h.new Thing(31);
...
因为如果没有Hello
,它并不意味着Thing
。
有关嵌套/内部类的更多信息: Nested Classes (The Java Tutorials)
【讨论】:
您的回答既全面又综合。即使感觉很奇怪(至少对我来说),语法是正确的。 如果还有人遇到错误,语法Thing thing1 <<HelloInstantiation>>.new Thing()
是关键。我花了几分钟混淆使用语法Thing thing1 new <<HelloInstantiation>>.Thing()
。 =P
@skia.heliou 谢谢!我正在制作一个辅助类和静态变量(甚至类),不仅消除了作用域,而且它们通常效率低下。需要提供运行时参数使得使用 main 方法很麻烦。这就是我所需要的,正是我想要找到的。【参考方案4】:
让我们通过下面的简单示例来理解它。 发生这种情况是因为这是非静态内部类。你应该需要外部类的实例。
public class PQ
public static void main(String[] args)
// create dog object here
Dog dog = new PQ().new Dog();
//OR
PQ pq = new PQ();
Dog dog1 = pq.new Dog();
abstract class Animal
abstract void checkup();
class Dog extends Animal
@Override
void checkup()
System.out.println("Dog checkup");
class Cat extends Animal
@Override
void checkup()
System.out.println("Cat Checkup");
【讨论】:
【参考方案5】:嗯...这么多好的答案,但我想添加更多。简要介绍 Java 中的内部类——Java 允许我们在另一个类中定义一个类,并且 能够以这种方式嵌套类具有一定的优势:
它可以隐藏(它增加封装)其他类的类 - 如果该类仅由它包含的类使用,则尤其相关。在这种情况下,外界就不需要知道了。
它可以使代码更易于维护,因为这些类在需要它们的地方按逻辑分组在一起。
内部类可以访问其包含类的实例变量和方法。
我们主要有三种Inner Classes
-
局部内
静态内部类
匿名内部类
需要记住的一些要点
我们需要类对象来访问它所在的本地内部类。 静态内部类可以直接访问,就像它所在的同一类的任何其他静态方法一样。 匿名内部类对外部世界以及同一类的其他方法或类(其中存在)不可见,并且在声明它的位置使用。让我们试着实际看看上面的概念_
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!");
我希望这对每个人都有帮助。请refer for more
【讨论】:
建议改进:将第一个类命名为 MyOuterClass,从 AnonymousClass 周围删除 cmets。【参考方案6】:将 INNER 类 Thing 声明为 static,它可以正常工作。
我记得当我将内部类 Dog 声明为 class Dog 时,我遇到了同样的问题。我遇到了和你一样的问题。 有两种解决方案:
1- 将内部类 Dog 声明为静态。 或者
2- 将内部类 Dog 自己移动到一个新类中。
示例如下:
公共类 ReturnDemo
public static void main(String[] args)
int z = ReturnDemo.calculate(10, 12);
System.out.println("z = " + z);
ReturnDemo.Dog dog = new Dog("Bosh", " Doggy");
System.out.println( dog.getDog());
public static int calculate (int x, int y)
return x + y;
public void print( )
System.out.println("void method");
return;
public String getString()
return "Retrun String type value";
static class Dog
private String breed;
private String name;
public Dog(String breed, String name)
super();
this.breed = breed;
this.name = name;
public Dog getDog()
// return Dog type;
return this;
public String toString()
return "breed" + breed.concat("name: " + name);
【讨论】:
【参考方案7】:Java 14 之前
您必须添加 static 关键字才能从静态上下文访问类 Thing
。
class Hello
static class Thing
public int size;
Thing()
size = 0;
public static void main(String[] args)
Thing thing1 = new Thing();
System.out.println("Hello, World!");
Java 14+ 从 Java 14 开始,您可以使用内部记录类,它们是隐式静态的。所以你会:
class Hello
record Thing(int size)
public static void main(String[] args)
Thing thing1 = new Thing(0);
System.out.println("Hello, World!");
【讨论】:
请注意,size
在使用记录时将是 final
。【参考方案8】:
我的朋友试试这个:(你也可以叫它 Hello 而不是 Main)
class Thing
public int size;
Thing()
size = 0;
class Main
public static void main(String[] args)
Thing thing1 = new Thing();
System.out.println("Hello, World!");
这背后的想法是您必须创建一个单独的类来包含静态 void main (String[] args) 方法。总结:您必须有一个将创建您的对象的类,以及另一个包含对象创建的类(在前一个之外)。如果你称它为 Main,你应该有一个名为 Main.java 的文件。如果你想叫它Hello,那么你的文件必须命名为Hello.java
【讨论】:
以上是关于是啥导致错误“无法访问 Foo 类型的封闭实例”,我该如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
是啥导致 cellForRowAtIndexPath 中的 outOfBounds 错误?
是啥导致 HttpListener HTTP 503 错误?