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.