是什么导致错误“没有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程序没有它编译也很好。只有我定义的类不及格。

它拒绝编译。我在创建新Thing的那一行得到No enclosing instance of type Hello is accessible."。我猜是:

  1. 我有系统级的问题(在DrJava或我的Java安装)或
  2. 我对如何在java中构建一个工作程序有一些基本的误解。

什么好主意吗?

324027 次浏览

Thing是一个自动连接到Hello实例的内部类。你会得到一个编译错误,因为没有Hello实例供它附加。你可以通过将其更改为没有连接的静态嵌套类来最容易地修复它:

static class Thing

static class Thing将使你的程序工作。

实际上,你已经得到了Thing作为一个内部类,它(根据定义)与Hello的特定实例相关联(即使它从未使用或引用它),这意味着在作用域中没有特定的Hello实例而说new Thing();是错误的。

如果将其声明为静态类,则它是一个“嵌套”类,不需要特定的Hello实例。

你已经将类Thing声明为一个非静态内部类。这意味着它必须与Hello类的实例相关联。

在代码中,您试图从静态上下文中创建Thing的实例。这就是编译器抱怨的地方。

有一些可能的解决方案。使用哪种解决方案取决于您想要实现的目标。

  • Thing移出Hello类。

  • Thing改为static嵌套类。

    static class Thing
    
  • Create an instance of Hello before creating an instance of 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
    }
    

The last solution (a non-static nested class) would be mandatory if any instance of Thing depended on an instance of Hello to be meaningful. For example, if we had:

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

关于嵌套/内部类的更多信息: 嵌套类(Java教程) < / p >

让我们用下面的简单例子来理解它。 这是因为它是非静态的内部类。你需要外部类的实例
 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");


}
}
}
< p >嗯…很多很好的答案,但我想补充更多。简要介绍Java中的内部类——Java允许我们在另一个类和类中定义一个类 能够以这种方式嵌套类有一定的优势:

  1. 它可以隐藏(它增加封装)类从其他类-特别是当类只被它所包含的类使用时。在这种情况下,没有必要让外界知道。

  2. 它可以使代码更易于维护,因为类在需要的地方被逻辑地分组在一起。

  3. 内部类对其包含类的实例变量和方法具有访问

我们主要有三种< >强Inner Classes < / >强类型

  1. 当地的内心
  2. 静态内部类
  3. 匿名内部类

要记住一些要点

  • 我们需要类对象来访问它所在的局部内部类。
  • 静态内部类可以直接访问,就像它存在于同一类的任何其他静态方法一样。
  • 匿名内部类对外部世界以及同一类(存在于其中)的其他方法或类都是不可见的,并且在声明时使用它。

让我们试着实际地看待上面的概念_

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!");
}
}


}

我希望这对大家都有帮助。请更多信息请参考

内心的类Thing声明为静态,它将毫无问题地工作。

我记得当我将内部类Dog声明为类 {only时,我也有同样的问题。我和你有同样的问题。有两种解决方案:

1-将内部类Dog声明为静态。

2-移动内部类狗自己到一个新的类。

下面是例子:

公共类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);
}
}

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!");
}
}

朋友,试试这个吧(你也可以叫它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

class Hello {
class Thing {
public int size;


Thing() {
size = 0;
}
}


public static void main(String[] args) {
        

PlayGround obj = new PlayGround();
        

Thing obj2 = obj.new Thing();
        

System.out.println("Hello, World!");
}
}

在我的例子中,这是因为多了一个'}'

实际上你不需要将任何东西声明为静态的,但是你必须指定一些外围实例,可以隐式地在同一个类中,显式地在new之前,或者显式地在构造函数中。

class A {


class B {
final A a = A.this;
}


class C extends B { }


final B b = new B();
final C c = new C();


}


class D extends A.B {


public D(A a) {
a.super();
}


}


class E {


final A   a =     new A();
final A.B b =   a.new B();
final A.C c = b.a.new C();
final D   d =     new D(a);


}