Nested class in Java

Asked

Viewed 591 times

10

I need to have nested classes in Java. Why the following implementation doesn’t work?

public class A{
    private class B{
        public B(){
            System.out.println("class B");
        }
    }

    public static void main(String[] args){
         A a = new A();
         B b = new B();
    }
} 

On the line I try to instantiate the Inner class B, the following error occurs:

No enclosing instance of type A is accessible

  • Hello rogger, welcome to [en.so], could you give us more details? For example, which error occurs? In which line?

  • On the line I try to instantiate the Inner class B, the following error occurs: No enclosing instance of type A is accessible.

  • 3

    Class B and private, so can only be instantiated from an instance of class A.

  • @Lucasvirgili In fact it is not because it is "private", it is for B be a member of A; even though B was not private, this code would only work if main were not static.

2 answers

5

Your code does not work because you are trying to access a non-static member of A (the nested class B) from a static method (static main); and you can only access non-static members of a class from a class instance.

So for your code to work, you have 3 options:

Instantiate B from an instance of A:

public class A{
    private class B{
        public B(){
            System.out.println("class B");
        }
    }

    public static void main(String[] args){
         A a = new A();
         B b = a.new B(); // instância de B a partir de uma instância de A
    }
} 

Change the method main for non-static, because if it is an instance method, it has access to non-static members of its class:

public class A{
     private class B{
        public B(){
            System.out.println("class B");
        }
    }
    // instância de B a partir de um método não estático de A    
    public void doSomething(String[] args){ 
        // A a = new A();
         B b = new B();
    }
} 

Or declare B as a static class, so it is accessible from static members (in this case, the method main).

public class A{
     // B declarado como classe estática
     private static class B{
        public B(){
            System.out.println("class B");
        }
    }

    public static void main(String[] args){
         A a = new A();
         B b = new B();
    }
} 

Update: In the second example, I changed the name of the method so that it would not be confused as an input method for a Java main class, as it would need to be static. This code has only the didactic role on nested classes.

  • I didn’t like your second option. You did an aberration with the main method, there’s no way you can run this code. The main method MUST be static, there is no other option.

  • Don’t travel, @Math. A a = new A(); a.main(new String[] { "parametro 1" });. Here’s the code running. Where’s the freak? It was not asked "how to run this code as an input method in a JAR main class or by command line using Java". Doubt is about nested classes.

  • @Math Now that you understand, unfold it there and give my +1 :D

  • Yes, I understood that you can make a method with the main name without it being "O" main method, but wouldn’t it be better if you made that clear in your answer? Another thing, after 15 min the vote was given it gets blocked, be it positive or negative, so I can change my vote you needed to edit anything in your post, and I would be very happy if the issue was changing the name of the main method that is not so main :)

3


You can’t instantiate in the direct way you did. A reference to the parent class is required so first you need to create an instance of it and in this instance access the inner class. Look at this example I got from a tutorial on internal classes:

public class InnerClassTest {
    public void foo() {
        System.out.println("Outer class");
    }

    public class ReallyInner {
        public void foo() {
            System.out.println("Inner class");
        }

        public void test() {
            this.foo();
            InnerClassTest.this.foo();
        }
    }

    public static void main(String[] args) {
        InnerClassTest o = new InnerClassTest();
        InnerClassTest.ReallyInner i = o.new ReallyInner();
        i.test();
    }
}

I put in the Github for future reference.

  • 1

    It’s not really about the visibility of B but rather the fact that he is a non-static member of A, so that it can only be accessed from an instance of A. To be accessible without an instance of A, B would need to be a static member. See my answer. cc @rogger.

  • The @Caffé is right. Both the main method and the private class B are within the same class, the class A, so there is no visibility problem of the Inner class. A simple B b = a.new B(); solves the AP problem, or change the class B to Static.

  • 1

    Nice edit to remove the note on the "private". Still missing answer the question "Why?".

  • It was already said only that I had other words

Browser other questions tagged

You are not signed in. Login or sign up in order to post.