Java - Nenhuma instância anexa do tipo Foo está acessível


314

Eu tenho o seguinte código:

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

Sei Thingque não faz nada, mas meu programa Hello, World é compilado sem ele. São apenas minhas classes definidas que estão falhando comigo.

E ele se recusa a compilar. Eu chego No enclosing instance of type Hello is accessible."na linha que cria uma nova coisa. Eu estou supondo:

  1. Tenho problemas no nível do sistema (no DrJava ou na minha instalação em Java) ou
  2. Eu tenho alguns mal-entendidos básicos de como construir um programa de trabalho em java.

Alguma ideia?


Respostas:


483

static class Thing fará seu programa funcionar.

Como é, você tem Thinguma classe interna, que (por definição) está associada a uma instância específica de Hello(mesmo que nunca a use ou se refira a ela), o que significa que é um erro dizer new Thing();sem ter uma Helloinstância específica em escopo.

Se você a declarar como uma classe estática, é uma classe "aninhada", que não precisa de uma Helloinstância específica .


Isso também significa que, se eu instanciar o outer class, o non-static inner classseria criado também, mesmo que eu não o usasse em nenhum lugar?
— Mr5

Não. Cada objeto de uma classe interna deve ter um pai, mas um pai pode ter qualquer número de crianças, incluindo 0.
— jacobm

92

Você declarou a classe Thingcomo uma classe interna não estática. Isso significa que ele deve estar associado a uma instância da Helloclasse.

No seu código, você está tentando criar uma instância de Thingum contexto estático. É disso que o compilador está reclamando.

Existem algumas soluções possíveis. Qual solução usar depende do que você deseja alcançar.

  • Saia Thingda Helloclasse.

  • Mude Thingpara ser uma staticclasse aninhada.

    static class Thing
  • Crie uma instância de Helloantes de criar uma instância de 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
    }
    

A última solução (uma classe aninhada não estática ) seria obrigatória se qualquer instância Thingdependesse de uma instância Hellopara ser significativa. Por exemplo, se tivéssemos:

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;
        }
    }
    ...
}

qualquer tentativa bruta de criar um objeto de classe Thing, como em:

Thing t = new Thing(31);

seria problemático, pois não haveria um enormousvalor óbvio para testar 31 contra ele. Uma instância hda Helloclasse externa é necessária para fornecer este h.enormousvalor:

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

Porque isso não significa a Thingse não tiver a Hello.

Para obter mais informações sobre classes aninhadas / internas: Classes aninhadas (The Java Tutorials)


Sua resposta é abrangente e sintética. Mesmo que pareça estranho (pelo menos para mim), a sintaxe está correta.
— boumbh

Se alguém ainda estiver recebendo erros, a sintaxe Thing thing1 <<HelloInstantiation>>.new Thing()é a chave. Passei alguns minutos confusos usando a sintaxe Thing thing1 new <<HelloInstantiation>>.Thing(). = P
— skia.heliou 15/01/15

1
@ skia.heliou Obrigado! Eu estava criando uma classe auxiliar e variáveis ​​estáticas (ou mesmo classes) não apenas eliminam o escopo, mas são frequentemente ineficientes. A necessidade de fornecer argumentos de tempo de execução dificulta o uso de um método principal. Era tudo o que eu precisava e exatamente o que estava procurando.
— Carrinho abandonado

25

Bem ... tantas boas respostas, mas quero acrescentar mais. Uma breve olhada na classe Inner em Java - Java nos permite definir uma classe dentro de outra classe e poder aninhar classes dessa maneira tem algumas vantagens:

  1. Pode ocultar (aumenta o encapsulamento) a classe de outras classes - especialmente relevante se a classe estiver sendo usada apenas pela classe em que está contida. Nesse caso, não há necessidade do mundo exterior saber sobre isso.

  2. Isso pode tornar o código mais sustentável, pois as classes são logicamente agrupadas em torno de onde são necessárias.

  3. A classe interna tem acesso às variáveis ​​e métodos da instância de sua classe que contém.

Temos principalmente três tipos de Inner Classes

  1. Local interno
  2. Classe interna estática
  3. Classe interna anônima

Alguns dos pontos importantes a serem lembrados

  • Precisamos de um objeto de classe para acessar a Classe Interna Local em que ela existe.
  • A classe interna estática é acessada diretamente da mesma forma que qualquer outro método estático da mesma classe em que existe.
  • Classe interna anônima não é visível para o mundo exterior, bem como para outros métodos ou classes da mesma classe (na qual existe) e é usada no ponto em que é declarada.

Vamos tentar ver os conceitos acima praticamente_

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

}

Espero que isso ajude a todos. Por favor, consulte para mais


Melhorias sugeridas: nomeie a primeira classe MyOuterClass, remova os comentários de AnonymousClass.
— Noumenon

9

Thingé uma classe interna com uma conexão automática a uma instância de Hello. Você recebe um erro de compilação porque não há nenhuma instância Hellopara anexar. Você pode corrigi-lo mais facilmente alterando-o para uma classe aninhada estática que não possui conexão:

static class Thing

9

Vamos entendê-lo com o seguinte exemplo simples. Isso acontece porque essa é a CLASSE INTERNA NÃO ESTÁTICA. Você deve precisar da instância da classe externa.

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

        }
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.