4

I would like to know if there any advantage of adding an inner class over a java class in a new file. Assuming these are only the two ways i can achieve that is needed. But I would only like to which one is a better approach of these two.

class ABC{ 
  LMN obj;
   public static class xyz{
     @customAnnotation LMN lmn; 
     public void set(ABC abc){
      abc.obj = lmn;
     }
   }
}

or have a separate class like this

public class xyz{
     @customAnnotation LMN lmn;
     public void set(ABC abc){
      abc.obj = lmn;
     }
}
Nishant
  • 71
  • 1
  • 6
  • "Assuming these are only the two ways i can achieve that is needed." Why don't you ask the question that actually is your problem then? Maybe the best solution is totally different. Classic xy problem – leonardkraemer Jan 03 '19 at 15:29
  • @leonardkraemer I believe the OP was asking for general knowledge rather than to solve a specific coding issue, but I could be wrong. – yuvgin Jan 03 '19 at 15:35
  • "the two ways" you can also declare multiple top-level classes in a file, provided at most one is public. However, this is discouraged (merely mentioning it to show there are more ways). – Andy Turner Jan 03 '19 at 15:59

5 Answers5

4

This is mainly a question of design.

From the JAVA SE Docs:

Why Use Nested Classes?

It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

Meaning if you only need to create and use instances of the class xyz within the context of the class ABC, then it makes sense for you to define it as an inner class inside ABC.

Doing so hides the inner class from the outside world, and gives the outer class access to its private data members (generally speaking, read more below). This makes your code easier to read and easier to understand, but more importantly it increases encapsulation and data hiding - ensuring the class is only visible to and accessible by those who need to use it. This is a fundamental principle in Object Oriented Programming.


On a more practical note:

There are two different types of nested classes in Java: static and non-static. Each type defines a different access-privileges relationship with its defining outer class. You can read more about the differences here.

yuvgin
  • 1,322
  • 1
  • 12
  • 27
3

There are a few advantages, most of which are access control-related:

  1. Unless this was included inadvertently in your question, the first advantage is right in your post (package-private access). ABC being package-private, ABC.xyz cannot be statically referenced outside the package. So a nested class allows for better access control (xyz can even be private or protected).
  2. ABC.xyz can access private ABC members (static ones), which removes the need for exposing encapsulated fields to the world if accessing them from xyz is required
  3. Regarding readability, a nested class makes coupling obvious (assuming it is right)
ernest_k
  • 44,416
  • 5
  • 53
  • 99
1

The only real difference is that the static inner class would have access to the private static members and methods in the parent, where the separate class would not.

robkin
  • 56
  • 5
0

It is usually used for inner object representations or to offer a public builder if you follow the builder pattern.

0
  1. Non-static classes inside a container

The example indeed leads to the advantage of having a non-static inner class:

class ABC { 
    LMN obj;
    List<Xyz> xyzs = new ArrayList<>();

    public class Xyz {
        @customAnnotation LMN lmn; 
        public void foo(){
            ABC.this.obj = lmn;
       }
    }


    ... new Xyz(); // Passes the this of ABC.
}

One might make the constructor of Xyz private in order to allow only ABC the correct creation of Xyzs.

Namely that ever Xyz knows the ABC that created it: ABC.this. Useful for containers.

  1. For method/stream related value holders

For static inner classes it can be a local use inside the class itself, or a parameter/result/exception class for a method in ABC, bound to the usage of class ABC.

Such a class is useful, as the API will not change when the parameter of a method is just Xyz, but Xyz gets and additional field. Would the method get an additional field, all usages would need to be updated. For a library that could make backward compatibility more awkward (a new method).

For lambdas with a classical forEach, or for loops such a static class might be useful too.

  1. Already often used: local enums

Finally enums defining a domain value range, are often also local to a class.

  1. Uses in standard java

In standard java there is the case of Character with extensive Unicode support in the form of inner classes Character.SubSet, UnicodeBlock, UnicodeScript.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138