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


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
    }
    

의미있는 인스턴스에 의존하는 인스턴스 가있는 경우 마지막 솔루션 ( 비 정적 중첩 클래스)은 필수 입니다. 예를 들어 다음과 같은 경우ThingHello

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과 같이 class 객체를 생성하려는 모든 원시 시도 :

Thing t = new Thing(31);

enormous31에 대해 테스트 할 명백한 가치 가 없기 때문에 문제가 될 수 있습니다 . 이 값 을 제공 h하려면 Hello외부 클래스 의 인스턴스 가 필요 h.enormous합니다.

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

가없는 Thing경우를 의미하지 않기 때문에 Hello.

중첩 / 내부 클래스에 대한 자세한 내용 : 중첩 클래스 (Java 자습서)


당신의 대답은 포괄적이고 종합적입니다. 그것이 이상하다고 느끼더라도 (적어도 나에게는) 구문이 정확합니다.
boumbh

누구든지 여전히 오류가 발생하면 구문 Thing thing1 <<HelloInstantiation>>.new Thing()이 핵심입니다. 나는 구문을 사용하여 몇 분 혼란했다 Thing thing1 new <<HelloInstantiation>>.Thing(). = P
skia.heliou

1
@ skia.heliou 감사합니다! 나는 도우미 클래스와 정적 변수 (또는 클래스)를 만들어 범위를 제거 할뿐만 아니라 종종 비효율적입니다. 런타임 인수를 제공 할 필요가 있으면 기본 메소드를 사용하는 것이 귀찮습니다. 이것이 내가 필요한 전부 였고 정확히 내가 찾던 것입니다.
버려진 카트

25

글쎄요 ... 좋은 답변이 많지만 더 추가하고 싶습니다. Java-Inner의 내부 클래스를 간략하게 살펴보면 다른 클래스 내에 클래스를 정의 할 수 있으며 이러한 방식으로 클래스를 중첩 할 수 있다는 장점이 있습니다.

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

}

이것이 모두에게 도움이되기를 바랍니다. 자세한 내용은 참조하십시오


개선 제안 : 첫 번째 클래스 이름을 MyOuterClass로 지정하고 AnonymousClass 주변에서 주석을 제거하십시오.
누 메논


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.