我有以下代码:

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的行中,我得到了Hello类型的No封闭实例。我猜是:

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

什么好主意吗?


当前回答

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

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

        }
    }
}

其他回答

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

static class Thing

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

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

}

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

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

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

将Thing移出Hello类。 将Thing更改为静态嵌套类。 静态类 在创建Thing实例之前,先创建Hello实例。 public static void main(String[] args) { Hello h = new Hello(); Thing thing1 = h.new Thing();//希望这个语法是正确的,键入在飞行 }

如果任何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);

这是有问题的,因为没有明显的巨大价值来测试31。需要一个Hello外部类的实例h来提供这个h.enormous值:

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

因为如果没有"你好"就不代表"事"了。

有关嵌套/内部类的更多信息: 嵌套类(Java教程)

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

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

        }
    }
}

Java 14之前 您必须添加静态关键字来从静态上下文访问类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!");
    }
}