8

I'm new to Java (have experience with C#),

this is what I want to do:

public final class MyClass
{
    public class MyRelatedClass
    {
      ...
    }
}

public class OtherRandomClass
{
    public void DoStuff()
    {
       MyRelatedClass data = new MyClass.MyRelatedClass(); 
    }
}

which gives this error in Eclipse:

No enclosing instance of type BitmapEffects is accessible. Must qualify the allocation with an enclosing instance of type BitmapEffects (e.g. x.new A() where x is an instance of BitmapEffects).

This is possible in C# with static classes, how should it be done here?

Dimitar
  • 4,402
  • 4
  • 31
  • 47
Mervin
  • 1,103
  • 4
  • 18
  • 26
  • Possible duplicate of [Java - No enclosing instance of type Foo is accessible](http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type-foo-is-accessible) – fabian Mar 03 '16 at 23:46

4 Answers4

19

The way you've defined MyRelatedClass, you need to have an instance of MyClass to be able to access/instantiate this class.

Typically in Java you use this pattern when an instance of MyRelatedClass needs to access some fields of a MyClass instance (hence the references to an "enclosing instance" in the compiler warning).

Something like this should compile:

public void doStuff() {
   MyClass mc = new MyClass();
   MyRelatedClass data = mc.new MyRelatedClass(); 
}

However, if a MyRelatedClass instance does not need access to fields of it's enclosing instance (MyClass's fields) then you should consider defining MyRelatedClass as a static class, this will allow the original code you've posted to compile.

The difference in having a nested class (what you've posted) and a static nested class (a static class within a class) is that in the former, the nested class belongs to an instance of the parent class, while the latter has no such relationship - only a logical/namespace relationship.

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 4
    Creating a (non-static) inner class on anything other than an implicit `this` makes me ill. – Tom Hawtin - tackline Jun 14 '10 at 17:34
  • well I'm trying to accomplish what I can do in c# : //[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } } I want 2 classes (non-static) in 1 file, somehow in Java this isn't allowed.. error: "the public type *name* needs to be defined in it's own file" so this was my solution to that, I want 1 package and I want to have related class grouped in their own file – Mervin Jun 14 '10 at 17:47
  • @Mervin as you've seen Java only allows one public top-level class per file. Related classes can just be defined in the same package, in separate files. – matt b Jun 14 '10 at 18:29
4

Try defining MyRelatedClass as static.

edit
More on the subject
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
  • I do not want MyRelatedClass to be static , I need multiple instances of it. – Mervin Jun 14 '10 at 17:32
  • 1
    @Mervin please read description in the link (or matt's answer). If inner class is 'static', it doesn't mean there's only one instance of it. It means MyRelatedClass won't be associated to any particular instance of MyClass and won't be able to access its (parent class') instance members. – Nikita Rybak Jun 14 '10 at 17:38
  • @Mervin - That is not what static means in this context. It effectively makes behave like a top-level class even though it is nested in MyClass. – Robin Jun 14 '10 at 17:40
  • well I'm trying to accomplish what I can do in c# : //[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } } I want 2 classes (non-static) in 1 file, somehow in Java this isn't allowed.. error: "the public type name needs to be defined in it's own file" so this was my solution to that, I want 1 package and I want to have related class grouped in their own file – – Mervin Jun 14 '10 at 17:56
  • Java very much wants to make you have one public class per file. It's highly recommended that you stick with that, rather than trying to hack around it. – Steven Schlansker Jun 14 '10 at 18:08
2

In response to the comments about packaging multiple classes in one file: unlike .NET, most implementations of java enforce a strict correlation between the name of public class type and the name of the file the class type is declared in. It's not a hard requirement, but not used a system where the correlation is not enforced. The JLS - 7.6 Top Level Type Declarations says this:

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).

See this SO question: multiple class declarations in one file

If you are looking to create a namespace to enclose your related classes, then using static inner classes are what you need. The static declaration does not mean one instnace - they can still be instantiated - the static means that they can be instantiated without needing a reference to the enclosing class. As the enclosing class is just for grouping, and not data, you are safe making it a static. To make it clearer that the enclosing class is just for grouping, you should declare it as an interface, so that it cannot be instantiated and has no implementation details.

Although personally, I would refrain from doing this - in Java, packages are used to enforce a namespace. Using inner classes for this quickly becomes cumbersome. (I have tried it!)

Community
  • 1
  • 1
mdma
  • 56,943
  • 12
  • 94
  • 128
0

Yes, non static nested classes have access to the outer classes instance members, and therefore must be created for an instance of the outer class. So you have two choices:

  1. make the nested class static as Mervin suggests, or
  2. create it using an instance of the outer class as the error message suggests.

In practice, I rarely create an instance of the inner class, except in methods of the outer class, and I rarely make such classes mutable -- but this is just me.

dsmith
  • 1,978
  • 10
  • 16
  • well I'm trying to accomplish what I can do in c# : //[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } } I want 2 classes (non-static) in 1 file, somehow in Java this isn't allowed.. error: "the public type name needs to be defined in it's own file" so this was my solution to that, I want 1 package and I want to have related class grouped in their own file – – Mervin Jun 14 '10 at 17:56