4

I found a couple of posts resembling this, but couldn't find an answer that trenchantly explains this.. I have performed nesting of a class, i.e class 'inside' is present in class 'outside' and made an attempt to instantiate the inner class, and this is the scenario that i came across through

In case of C# :

    class outside
    {
        public class inside
        {
            public void print()
            {
                System.Console.WriteLine("I am inside");
            }
        }
    }
    class Program
    {
        public static void Main(string[] args)
        {
            /* here i am trying to instantiate the inner class 'inside' */
            outside.inside obj = new outside.inside();
            obj.print();
            Console.ReadKey();
        }
    }

Output:

I am inside So, the above is working fine..But,
In case of Java :

class outside
{
    public class inside
    {
        public void print()
        {
            System.out.println("I am inside");
        }
    }
}
class Demo
{
    public static void main(String[] args)
    {
        /* here i am trying to instantiate the class 'inside' */
        outside.inside obj=new outside.inside();
        obj.print();
    }
} 

Output:

Demo.java:16: error: an enclosing instance that contains outside.inside is required...

This is the situation in case of Java.. What this error is ?

Does it mean that the outer class 'outside' cannot access inner class 'inside' using the dot operator because it is not static? If so, then why the same doesn't generate a compilation error in c# ?

2
  • static class has quite different meanings in the two languages (and, thus, what a non-static class means). This comes into play in inner classes. You might want to look up static class in each context to help it make sense. Commented Jun 7, 2013 at 14:46
  • possible duplicate of An enclosing instance that contains <my reference> is required Commented Sep 26, 2013 at 12:41

4 Answers 4

11

The problem is that the way you have declared classes in Java, the inner class has an implicit reference to an instance of the outer class. Hence the error message: "error: an enclosing instance that contains outside.inside is required". This means you need to:

Outside out = new Outside();
Outside.Inside in = out.new Inside();

In general, this pattern is used in Java in situations where it makes no sense for an instance of the inner class to exist without an instance of the outer class; and note that the inner class instance will have access to all of the outer class instance's variables, even private ones. But in general, such classes are generally private.

In order for this to disappear, you must make the inner class static. And then you will be able to do:

Outside.Inside in = new Outside.Inside();

Edit: completent on what static means in Java: static whatevers (variables, classes, methods) in Java are accessible at the class and instance level. You can access a static variable from a non static method for instance (this also means you can call static methods from an instance of a class!); but a static method CANNOT access a non static variable, nor invoke an "instance only" method etc.

Also, a "top level" class cannot be static, because it makes no sense.

Sign up to request clarification or add additional context in comments.

5 Comments

In Java in general, inner classes should be private (or public if you need) static class MyInnerClass unless you explicitly need a reference to the containing class. Even this can be accomplished by passing in the object reference on creation. In my opinion this should have been the default behaviour, b/c it's more clear, but anyway, there is still a solution
Well, that is what I said... And note what I said about instance variables as well. If the inner class is static, you don't have access to them (save for static variables, of course, but they have links to the class, not the instance).
@fge yeah.. & what in case of C# ? how is the inner architecture designed to handle such classes ?
@SrinivasCheruku what do you mean by "inner architecture"? More generally, you should know that static in Java means the variable, or class, is accessible at the class level. C#'s nested classes are equivalent to Java's nested static classes for this reason. When there is no static in Java, an enclosing instance must exist for the methods/variables/etc (and classes!) to be accessible at all.
Correction: static whatevers in Java are accessible at the class and instance level. You can access a static variable from a non static method for instance; but a static method CANNOT access a non static variable.
2

The syntax for nested classes in Java is slightly different from C#. Here is a better comparison of the two. By looking at the C# translations of the following two passages of Java code, you can get a better idea for what Java's doing behind the scenes. For an additional reference, see this link.

A static nested class in Java works like a nested class in C#.

Java:

class Outside {
    public static class Inside {
        public void print() {
            System.out.println("I am inside");
        }
    }
}

class Demo {
    public static void main(String[] args) {
        Outside.Inside obj = new Outside.Inside();
        obj.print();
    }
}

C#:

class Outside
{
    public class Inside
    {
        public void Print()
        {
            System.Console.WriteLine("I am inside");
        }
    }
}

class Program
{
    public static void Main(string[] args)
    {
        Outside.Inside obj = new Outside.Inside();
        obj.Print();
    }
}

An inner class (non-static nested class) in Java does not have a direct syntax translation in C#, but we can write the explicit equivalent.

Java:

class Outside {
    public class Inside {
        public void print() {
            System.out.println("I am inside");
        }
    }
}

class Demo {
    public static void main(String[] args) {
        Outside out = new Outside();
        Outside.Inside obj = out.new Inside();
        obj.print();
    }
}

C#:

class Outside
{
    public class Inside
    {
        private Outside _outer;

        public Inside(Outside outer)
        {
            if (outer == null)
                throw new ArgumentNullException("outer");

            _outer = outer;
        }

        public void Print()
        {
            System.Console.WriteLine("I am inside");
        }
    }
}

class Program
{
    public static void Main(string[] args)
    {
        Outside outside = new Outside();
        Outside.Inside obj = new Outside.Inside(outside);
        obj.Print();
    }
}

1 Comment

Oh man I wish had this C# translation a year ago when I started this android project. There are soooo many android-native java snippets that involve inner-classes that access the outer classes private instance members, and my translation's into mono/c# was to declare public members in the inner-classes that matched the outer classes members (whatever ones I needed), and then copy the values over. This method was horrible, especially making sure the inner members where always updated with the outer members, especially in an ansync event driven environment! Thank you so much for this grail.
1

In java,

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Why is this different in C#? Because it's another language.

1 Comment

@engima yeah.. but at the end of the day, everything ends up with the concepts of OOP, that has to be universal..
0

In C#, a nested class (including its static and non static methods) can access all static and non-static members and methods of an object of the type of the outer class, including the outer class itself, regardless of the protection level. The protection level only matters when accessing it from outside of the nested or outside of the outer class.

You cannot access the non-static members and methods of the outer class on an object of the type of the nested class, regardless of the protection level (it is not possible even if it is being accessed in the outer class or the nested class or another class entirely); you have to use an outer class object. Similarly, you cannot access the static members and methods of the outer class via the nested class name, you have to use the outer class name.

An outer class cannot access private members (static or non-static) of the nested class (via an object of the type of the nested class or via the nested class itself), but it can instantiate the class because the class type of the nested class itself is always accessible to the outer class. This means if the nested class is private but a static member is not private then it will be able to access the member, but if the member is private then it won't be able to access the member. In this instance accessing from the outer class is like accessing from another class in the assembly entirely.

You cannot access the non-static members and methods of the nested class on an object of the type of the outer class, regardless of the protection level; you have to use an inner class object. Similarly, you cannot access the static members and methods of the nested class via the outer class name, you have to use the inner class name.

In C#, the outer and nested class objects are always instantiated as separate objects, but you can place a reference to the outer class in the nested class and a reference to the nested class in the outer class.

In Java, the nested class is called an inner class if it is not static. An inner and outer class are instantiated separately but you need to use the outer object in order to instantiate the inner object, meaning that the inner object is always associated with an outer object. This means that you need to instantiate an outer object first. The inner object is however not a member of the outer object and the outer object is not a member of the inner object, so you have to explicitly make it one in order to be able access the object that it is paired with outside of the class. Inside the inner class however, you can access all outer object members and methods using outerclass.this.method using the special version of this – as you need this to do it, you can't access it outside of the inner class. Inside the outer class, you cannot access the inner object tied to an outer object using innerclass.this.method2 as the special this is used to get the outer object of the this object only. This is because an outer object can have many inner objects, so it would be ambiguous and is disallowed.

Another difference between Java and C# is the fact that you can access private inner members from within the outer class via an object of the type of the inner class (as paragraph 3 mentioned) in Java.

Another difference between Java and C# is that a static nested class in Java is different to the static nested classes of other languages like C++ and C#, for which there is no equivalent in Java. A static nested class in Java is a regular nested class in C# – It just removes the requirement that the nested class needs to be instantiated using an object of the outer class, instead an object of the outer and nested class can be instantiated separately, and hence the special this does not work either.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.