Java-Foo型の包含インスタンスにアクセスできません


314

私は次のコードを持っています:

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で動作するプログラムを構築する方法について、いくつかの基本的な誤解があります。

何か案は?


回答:


483

static class Thing プログラムを機能させます。

現状では、Thing(定義により)の特定のインスタンスに関連付けられている(定義により)Hello決して使用または参照しない場合でも、内部クラスとして取得します。つまりnew Thing();、特定のHelloインスタンスがないと言うのはエラーです。範囲。

代わりに静的クラスとして宣言する場合、それは「ネストされた」クラスであり、特定のHelloインスタンスを必要としません。


これはouter class、をインスタンス化すると、non-static inner classどこで使用しなくてもも作成されることを意味しますか?
mr5 '19年

いいえ内部クラスのすべてのオブジェクトが親を持っている必要がありますが、親は0を含む子どもの数に制限はありません
jacobm

92

クラス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をテストする明白な値がないので、問題があります。この値を提供するにはhHello外部クラスのインスタンスが必要h.enormousです。

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

これは、がなくても意味ThingがないからHelloです。

ネスト/内部クラスの詳細: ネストされたクラス(Javaチュートリアル)


あなたの答えは包括的かつ総合的です。奇妙に感じても(少なくとも私には)、構文は正しいです。
boumbh 2014

それでもエラーが発生する場合は、構文Thing thing1 <<HelloInstantiation>>.new Thing()が重要です。私は構文を使用して混乱して数分を費やしましたThing thing1 new <<HelloInstantiation>>.Thing()。= P
skia.heliou

1
@ skia.heliouありがとうございます!私はヘルパークラスと静的変数(またはクラス)を作成していただけでなく、スコープを削除するだけでなく、多くの場合非効率的です。ランタイム引数を提供する必要があるため、mainメソッドを使用するのは面倒です。これが私が必要とするすべてであり、まさに私が探していたものでした。
放棄されたカート

25

うーん...良い答えはたくさんありますが、さらに追加したいと思います。Javaの内部クラスの概要-Javaを使用すると、別のクラス内にクラスを定義できます。このようにクラスをネストできることには、次のような利点があります。

  1. それは他のクラスからクラスを隠す(カプセル化を増やす)ことができます-そのクラスが含まれているクラスによってのみクラスが使用されている場合は特に関連があります。この場合、外部の世界がそれを知る必要はありません。

  2. クラスは必要な場所で論理的にグループ化れるため、コードをより保守しやすくすることができます。

  3. 内部クラスは、それを含むクラスのインスタンス変数とメソッドにアクセスできます

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

}

これが皆さんのお役に立てば幸いです。詳しくはお問い合わせください


提案された改善:最初のクラスにMyOuterClassという名前を付け、AnonymousClassの周りからコメントを削除します。
Noumenon


9

次の簡単な例でそれを理解しましょう。これは非静的内部クラスであるために発生します。外部クラスのインスタンスが必要です。

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

        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.