Abstract: We have heard that we can only have one public class per .java file. But that is not entirely true. We could, in theory, have many public static inner classes inside one public class.
Welcome to the 80th edition of The Java(tm) Specialists' Newsletter. There is a saying in the English language: It never rains, but it pours. This means that either I am unbelievably busy, or I have time to write several newsletters at once. So, at the moment the sun is shining and I have the luxury of being able to relax with my hobby of writing newsletters.
The idea in this newsletter was prompted by a professor who attended my Java classes in China. I was talking about Java only allowing one public class per file, and he asked: "What about inner classes?" The resulting discussion ended up in this newsletter. Technically, it is possible to have lots of public static inner classes and use them as normal public classes, but I would strongly recommend against that.
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
Some of the most common complaints that I hear about Java are these:
I sometimes struggle to take these complaints seriously. Here are my standard answers:
Before I show you this approach, please understand that I do not endorse writing classes in this way. I prefer using one file per class, even for non-public classes. I once had to work on a class that had about one hundred inner classes. It was a nightmare.
We start by defining package eu.javaspecialists.tjsn
which
contains class All
. This class contains all the
classes as public static
inner classes.
package eu.javaspecialists.tjsn; public class All { public static class A { public void f() {} } public static class B { public void g() {} } public static class C { public void h() {} } public static class D extends A { public void f() {} } public static class E { public void jump() {} } public static class F { private final E e = new E(); public void skip() { e.jump(); } } }
It is important that the class is in a package, as we will see just now. Next we show the first approach of how we could now use classes A,B,C,etc.
import eu.javaspecialists.tjsn.All; public class AllTest1 { public static void main(String[] args) { All.A a = new All.A(); All.B b = new All.B(); All.C c = new All.C(); All.D d = new All.D(); All.E e = new All.E(); All.F f = new All.F(); } }
Admittedly, this is ugly. However, there is another approach. We can import the inner classes directly, like so:
import eu.javaspecialists.tjsn.All.*; public class AllTest2 { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); D d = new D(); E e = new E(); F f = new F(); } }
This is now a lot prettier than saying All.A and All.B. I think it only works if the class is in a package. This should not be a restriction since classes should be in packages anyway.
Here are some reasons why you should rather not do this: First, it is going to result in large source files. Second, all members of the classes will effectively only have package access protection. This can easily result in spaghetti code that would make an Italian Mama proud. Third, most IDEs will struggle to support this well. Fourth, I seem to recall that some compilers cannot compile importing of inner classes.
Kind regards
Heinz
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.