Is it bad to use large inner classes in Java?

I have many objects of type ContainedClass stored in an object of type ContainingClass . I need to access a container object from internal objects. At the moment, I am doing this by passing a reference to the container object in the constructor of other objects, such as ContainedClass cclass = new ContainedClass(this); and saving it as a ContainingClass owner .

It seems ugly to me, and a solution that seems appropriate to me uses inner classes, but the definition of ContainedClass is very large and seems inappropriate. So what options should I go with? Or is there another obvious option that I'm missing?

Here is a code snippet of the code that I found on the Internet, depicting what I will use for inner classes.

 public class TestIt { public static void main(String a[]){ new TestIt().doit(); /* output : Hello world! */ } public void doit() { new InnerClass().sayHello(); } public void enclosingClassMethod(){ System.out.println("Hello world!"); } class InnerClass { public void sayHello() { TestIt.this.enclosingClassMethod(); } } } 

I should add that another advantage of the inner classes that I was looking at was that a ContainedClass can only exist in a ContainerClass , which is the desired result.

+4
source share
6 answers

I think it depends on how strongly the parent / child classes are related. If a child needs access to many member variables that otherwise you could not open through getters / seters or many member functions that would otherwise be private, then the internal layout of the classes will be cleaner.

But if the child class will use the parent's existing public interface, then I think its separation is cleaner. Adding only one additional parameter to the constructor is not bad. You can even enter an interface to describe which parts of the parent are accessible from the child. This makes it easy to unit test the child class separately from the parent class (for example, using mock objects).

+2
source

What you did with your Construction ContainedClass cclass = new ContainedClass(this); exactly replicates what the inner classes do under the covers. There may be reasons not to use inner classes, but the size of the class is actually not one of them. I would use the function of the real language, rather than emulating it, if there was no good reason not to use the real deal.

+3
source

I would use factoryMethod in this case:

 class ContainingClass { ... ContainedClass createContainedObject() { return new ContainedClass(this); } ... } 

in code it will look like

 jar = new ContainingClass(); bean = jar.createContainingClass(); 

This is a bit of a problem, but I find it expressive and allows me to choose whether to use or not use the inner class. I personally do not like big internal classes, I find it difficult to read them.

+1
source

If I were you, I would stick to what you did before, instead of switching to inner classes. Their syntax is sometimes incompatible (especially since it is not a static inner class, but a class for each instance), and you just collect a lot of code in one file.

The parent / child relationship you used before is not all that unusual, and I don't find it ugly in person.

0
source

Larger classes of any taste should usually be underestimated, as they tend to have multiple responsibilities and are a pain for isolation and testing.

Your decision will ultimately depend on why the ContainedClass needs to know about ContainerClass. If the goal is to share a common data / initialization code between ContainedClasses, then the Factory approach can give good results. Or perhaps if you just want to keep track of your ContainedClasses, then you might need to consider the Event / EventListener model.

0
source
  • The inner class must be used to create garbage objects.
  • if only the top level class uses this class, then go for the inner class.
  • Please read Joshua Bloch's "Effective Java" for a clear idea.
0
source

All Articles