Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Is there a way to put nested classes in a separate file?

Tags:

I have a Java class that is about 4,000 lines long (lots of methods). This class then uses about 200 small classes that only it needs, so another 4,000 lines of code.

If this was C# I would put those other in a partial class file so different file, but they would remain private nested classes only visible to the parent class.

Is there a way to do this in Java? I'm not asking for some methods to be in a distinct file, but for private nested classes to be in a distinct file.

thanks - dave

like image 869
David Thielen Avatar asked Jan 14 '18 13:01

David Thielen


People also ask

Can we create separate classes as separate files in Java?

Of course you can separate out 2 classes and still they will work fine. Just make sure you import one class in another using import statement. All you need to do is move AnotherClass class into a separate source file named with name same as class name ie "AnotherClass.

Should classes be in separate files Java?

It is technically legal to have multiple Java top level classes in one file. However this is considered to be bad practice (in most cases), and some Java tools may not work if you do this.

Should each class be in a separate file?

It is good practice to do so. You can easily find the class if you name the file after the class.

Can we inherit nested class?

A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.


2 Answers

You can't make a class private to only another class while putting it in a different file.

Use no class access modifier

What you can do is put the classes in separate files with no access modifiers (omit "public"), which will make them package-private, i.e. visible only within its own package. See also the official Access Control tutorial.

UtilClasses.java:

package OurPackage;

class UtilClass1
{
}
class UtilClass2
{
}

MainClass.java:

package OurPackage;

public class MainClass
{
   UtilClass1 iAmAUtilClass;
}

Use interfaces or inheritance

You can also achieve something similar with either interfaces or inheritance, by omitting the access modifier from the nested class. This would also be package-private, but this might be preferable to the above in some circumstances, since it avoids having all the nested classes at the top level.

BaseInterface.java:

package OurPackage;

interface BaseInterface
{
   class UtilClass1
   {
   }
}

MainClass.java:

package OurPackage;

public class MainClass implements BaseInterface
{
   UtilClass1 iAmAUtilClass;
}

You can also use a base class instead of an interface and extend that with roughly the same effect.

You don't need to implement BaseInterface gain access to its nested classes, but, if you don't, you'd need to use BaseClass.UtilClass1 instead of just UtilClass1.

like image 137
Bernhard Barker Avatar answered Sep 23 '22 12:09

Bernhard Barker


Inner private classes can't be "extracted" and still be visible only to one particular class. One solution is already mentioned in the comments: Create a package that contains the "main" class and all the previously inner classes and make the inner classes package visible. This would also allow you to create unit tests testing for the correct functionalities of the inner classes, which is something that is most likely currently not happening simply because the inner classes can't be "reached" by a unit test at the moment.

Concepts like declaring "friendships" between classes like in C++ don't exist in Java.

like image 36
Lothar Avatar answered Sep 19 '22 12:09

Lothar