Java - 不能访问类型为Foo的封闭实例

时间:2012-03-05 01:31:17

标签: java inner-classes

我有以下代码:

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中构建一个工作程序有一些基本的误解。
  3. 有什么想法吗?

7 个答案:

答案 0 :(得分:448)

static class Thing将使您的计划有效。

实际上,你有Thing作为内部类,它(根据定义)与Hello的特定实例相关联(即使它从未使用或引用它),这意味着在new Thing();范围内没有特定Hello实例时说错Hello

如果你将它声明为静态类,那么它就是一个“嵌套”类,它不需要特定的{{1}}实例。

答案 1 :(得分:84)

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

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

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

  • Thing移出Hello课程。

  • Thing更改为static嵌套类。

    static class Thing
    
  • 在创建Hello的实例之前,创建{em} <{1>}的实例。

    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

会有问题,因为对它进行测试31不会有明显的Thing t = new Thing(31); 值。 enormous外部类的实例h是提供此Hello值所必需的:

h.enormous

因为如果... Hello h = new Hello(30); ... Thing t = h.new Thing(31); ... 没有Thing,它并不意味着Hello

有关嵌套/内部类的更多信息: Nested Classes (The Java Tutorials)

答案 2 :(得分:24)

嗯...这么多好的答案,但我想补充更多。简要介绍Java-Java中的Inner类允许我们在另一个类中定义一个类 能够以这种方式嵌套课程有一定的优势:

  1. 它可以隐藏(它增加封装)来自其他类的类 - 特别是如果该类仅由其所包含的类使用的话。在这种情况下,外界不需要了解它。

  2. 它可以使代码更易于维护,因为这些类在逻辑上围绕它们所需的位置组合在一起。

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

  4. 我们主要有三种 Inner Classes

    1. 本地内部
    2. 静态内在类
    3. 匿名内心阶层
    4. 要记住的一些要点

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

      让我们尝试实际看到上述概念_

      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

答案 3 :(得分:10)

让我们用以下简单的例子来理解它。 这是因为这是非静态内部类。你应该需要外类的实例。

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

        }
    }
}

答案 4 :(得分:9)

Thing是一个inner class,与Hello的实例自动连接。您收到编译错误,因为没有Hello的实例可以附加到它。您可以通过将其更改为无连接的static nested class来轻松解决此问题:

static class Thing

答案 5 :(得分:1)

INNER 类声明为静态,它将正常运行。

我记得当我将内部类Dog声明为 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);
}
}

}

答案 6 :(得分:0)

Java 14 之前 您必须添加 static 关键字才能从静态上下文访问类 class

Thing

Java 14+ 从 Java 14 开始,您可以使用内部记录类,它们是隐式静态的。所以你会:

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