What is benefit of using an inner static class? Where should I prefer it over other options?
And how is its memory allocated?
If the inner class is static, you don't need an instance of the outer class to instantiate it.
If the inner class is public, it's basically just a name-scoping technique for highlighting the fact that the class "belongs" to the outer class.
If you make the inner class private however, it can't be used outside of that class.
One of the most compelling reasons for using inner classes is composition. In case of composition the existence of one entity is solely for the purpose of its higher entity. For example a University. A university is composed of Departments. The departments has no individual existence outside the university. Moreover, the access to departments should be controlled by University. In this case, we can have the Department class as an inner class of the University class.
And how is its memory allocated?
The simple answer is that memory for an inner static class is allocated the same way as for a non-nested class. There is nothing special about this case, either with respect to instances of the classes or static members of the class.
Related
So I have to design a DTO in Java, in a way that I have a Profile which has many Roles. This DTO will be served to a front end application. So I create a class named ProfileDTO and a static inner class called Role.
public class Profile {
private List<Role> roles;
// ommiting getters/setters
public static class Role {
}
This way, if I want to create an instance of Role from outside I have to declare it like
var role = new Profile.Role();
I also saw another approach from a colleague of mine though. Have a separate Role class in the same package and just use
private List<Role> roles;
in Profiles class.
So which approach is better? And if it depends, what are the factors it depends on ?
Actually it depends on how you want to represent your domain. In example, if you want the Role class to be accessible to every other class or to have a specific visibility you could create an external class; otherwise, you could use an inner class to have explicitly stated the relation between the Role class and the Profile one.
To cite the tutorial from oracle docs:
Compelling reasons for using nested classes include the following:
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.
It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be
declared private. By hiding class B within class A, A's members can be
declared private and B can access them. In addition, B itself can be
hidden from the outside world.
It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is
used.
Moreover, regarding the static nested class,
A static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class: it can use them only through an object reference.
If the inner class is only used by the outer class, I will prefer your approach. It has an object-oriented advantage, an organizational advantage, and a call-back advantage according to https://www.infoworld.com/article/2077411/inner-classes.html . Simply speaking, it means the inner class is logically binded to the outer class so that the inner class can be easily accessed and maintained within the outer class.
However, if the above advantages disappear, inner class will remain code complexity and probably create redundant class for the program.
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
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.
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.
You can replace the inner classes with top-level ones, but you'll have to rewrite a lot of things by hand that the compiler auto-wires for you with the inner-class relationship. To the Virtual Machine, an inner class is nothing special, it's just another class in the same package as the outer class with a fancy name. But the compiler creates a lot of helper constructs under the hood, that you have to reconstruct by hand (or have some refactoring tool do that for you):
The inner class can refer to the outer this instance, by prefixing it with the outer class name. You need to pass the outer this into your inner constructor and store it in a field like outerThis to get access.
In the source code, you can call the outer-class methods directly. You need to rewrite it like outerThis.method(). The same applies to fields.
For private outer methods and fields to become accessible, the compiler creates bridge constructs for you. You have to either change access modifiers or create package-private bridge methods yourself.
In the end, you'll have the former inner classes at least package-visible and being more verbose than the original ones, but on the other hand you'll get better isolation and testability.
I was reading a code snippet:
Class MyDAO{
public static final MyDAO DAO = new MyDAO();
public void loadData(){
//Hibernate Code to do something
}
...
}
So I'm amazed, and questions I'm facing right now is:
as static keyword denotes that a "member variable, or method, can be accessed without requiring an instantiation of the class to which it belongs". In simple terms, it means that you can call a method, even if you've never created the object to which it belongs.
What is the use of declaring a data member as static and instantiating a class then? is it a design pattern or what? and Most Importantly what is use of that? Any how when you say Class.staticMember how is the class loaded into the memory of JVM?
It can be used to implement Singleton pattern.
Data member is to be declared when you want it to hold same value across all instances(shared between different object of the class)
Declaring static is not a design pattern, but it is a way to design your application.
Further to this if your member is only consumed by methods in class and it is not expected to be accessed directly you can make it private static.
This is a way of providing the DAO object to the rest of the application as a global object. It is crude and ugly and makes testing hard, because it's difficult to provide a mock implementation of the DAO.
Static members are initialized at the time that the class is loaded. Classes are loaded lazily when they are first referenced. Other classes in the application can access this DAO without having to initialize it.
Code like this is why Dependency Injection frameworks (Spring, Guice, Hivemind, etc.) were created. This code makes the application depend on a specific implementation instead of on an abstraction, using dependency injection reduces coupling and increases testability by having the application depend on an abstraction and having the DI container be in charge of selecting the implementation and enforcing singleton scope.
What is the use of declaring a data member as static and instantiating a class then?
Having a data member being static does not give you any reason for not instantiating that class, because your class may still contain other non-static members.
So when do you not have to instantiate the class?
When all your members are static such as a utility class. An example is the Math class in Java.
Most Importantly what is use of that?
If you class contains non-static members, how do you expect those data to be accessed if you do not instantiate the class? Remember that your non-static members will not exist in memory if the class they belongs to is not instantiated.
is it a design pattern or what?
It has no direct relation with design patterns. Generally, you declare a member as static when it is a behaviour or property of the class itself and not individual objects.
Any how when you say Class.staticMember class is loaded into the memory of JVM.
I won't know exactly how Java memory works internally, but static members exist even before object instantiation which means variables declared as static are already created and loaded during runtime.
That also implies static members actually belongs to the class (not individual instance).
Why ConcurrentHashMap.Segment and ConcurrentHashMap.HashEntry classes are static?
Why it is designed in this way ?
Basically all inner classes which does not need to use the properties of their enclosing classes are supposed to be static. This comes from the general principle in java which says that every object should have access to the least possible other objects.
Each inner non-static class contains an invisible field this$ which references it's parent object (ConcurrentHashMap) which creates an overhead of 8 bytes per entity (Segment or HashEntry). This is how parent's class fields are accessed - inner class is in some sort a syntax sugar for objects which belong to a single container (e.g. parent).
This is why inner classes should be replaced with static inner classes when possible.
#Andrey , #Adam I agree the points you presented but the real answer I got from effective java book. Item#22 Favor static member classes over nonstatic.
A common use of private static member classes is to represent
components of the object represented by their enclosing class.For
example, consider a Map instance, which associates keys with values.
Many Map implementations have an internal Entry object for each
key-value pair in the map. While each entry is associated with a map,
the methods on an entry (getKey, getValue, and setValue) do not need
access to the map. Therefore, it would be wasteful to use a nonstatic
member class to represent entries: a private static member class is
best.
If you declare a member class that does not require access to an
enclosing instance, always put the static modifier in its declaration.If you omit this modifier, each instance will
have an extraneous reference to its enclosing instance
lot more good stuff I got from item#22 but above are the main points.
Inner static class has a one beautiful feature that they are lazy loaded as it is explained in Bill Pugh Singleton Implementation, when we implement singleton pattern.
Other features that the static inner class provides is that the outside instance variables are not accessible. From here, we can not access non static methods either. There is no need to make separate instance to initialize that static class, Directly using ClassName.InnerStaticClass.method(), the method can be called.
I have class A with its inner class defined A1 and class B with its inner class defined B1. Do you think it is alright that class A in its implementation refers to B1 and class B refers to A1. Is it not a bad programming style? Its just A1 is very A specific class and B1 very B specific, that's why I coupled them. Is it Ok to leave it like that or its better to have A1 and B1 as separate classes? What do you think? Thx.
I believe that if you need to refer to inner classes of another class, in one of your classes, it is because possibly the class which holds the inner class should be providing some methods to avoid this problem.
If the problem is not like that, then the inner class is probably generic enough to be of use in both other classes, and as such should be an independant class, which should be probably part of the same package which specifies its context of application/use.
You could - though I would think the point of inner classes is because they should be used within the outer classes. In other words, I am not a big fan of public inner classes.
I would actually just put A1 and B1 out as its own class - seem to me A1 and B1 are not that specific to A and B after all since A1 is used by B and B1 is used by A.
Look at this post Why/when should you use nested classes "Use a nested class when the class you are nesting is only useful to the enclosing class"
I would possibly try to two things:
Move inner classes to the separate ones, as they are not inner any more in logical way.
Create some interfaces to make A and B not to know at least where the A1 and B1 classes are.
I'd say if both classes are in the same package, extract the inner classes and make them package private. That way, both classes (A and B) can refer to them but still they are invisible to other classes outside the package.
I think you've asked two separate design questions in one. The first question is about referring to another class's inner classes. The second question is about the circular dependency between A/A1 and B/B1.
Exposed Inner Classes
There are many reasons to use Java inner classes.
Group classes that are only relevant to one-another and the outer class. (a.k.a mini-package)
Reduce boilerplate code in passing and referring to outer class instances
Add an additional level of scoping beyond package
Expanding the semantics of Java's access scope... for example, private has a different meaning for outer-class -- inner-class interactions.
Reduce the explosion of source files... especially in (source) code generation scenarios.
Access to outer class internals for testing (the inner class can be removed during packaging of JAR).
Under many of these circumstances, referring to the inner class by name is perfectly reasonable.
Circular Dependency
This is more often a tell tale sign of needing to extract interfaces, or needing extract other specialized classes. If A1, B1 are too simple to extract interfaces etc, then perhaps you can use inner classes in a different way: Have outer class C, containing A1, B1.