Related
What is the main difference between an inner class and a static nested class in Java? Does design / implementation play a role in choosing one of these?
From the Java Tutorial:
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.
Static nested classes are accessed using the enclosing class name:
OuterClass.StaticNestedClass
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:
class OuterClass {
...
class InnerClass {
...
}
}
An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
see: Java Tutorial - Nested Classes
For completeness note that there is also such a thing as an inner class without an enclosing instance:
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.
The Java tutorial says:
Terminology: Nested classes are
divided into two categories: static
and non-static. Nested classes that
are declared static are simply called
static nested classes. Non-static
nested classes are called inner
classes.
In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, but I'll use the correct term "nested class" which covers both inner and static.
Classes can be nested ad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.
There are three reasons you might create a nested class:
organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
access: nested classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of nested class, whether inner or static).
convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context
There are four kinds of nested class in Java. In brief, they are:
static class: declared as a static member of another class
inner class: declared as an instance member of another class
local inner class: declared inside an instance method of another class
anonymous inner class: like a local inner class, but written as an expression which returns a one-off object
Let me elaborate in more details.
Static Classes
Static classes are the easiest kind to understand because they have nothing to do with instances of the containing class.
A static class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace, e.g. the class Goat declared as a static member of class Rhino in the package pizza is known by the name pizza.Rhino.Goat.
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
Frankly, static classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static class feature to exist.
Inner Classes
An inner class is a class declared as a non-static member of another class:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
Like with a static class, the inner class is known as qualified by its containing class name, pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an inner class is tied to a particular instance of its containing class: above, the Goat created in jerry, is implicitly tied to the Rhino instance this in jerry. Otherwise, we make the associated Rhino instance explicit when we instantiate Goat:
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(Notice you refer to the inner type as just Goat in the weird new syntax: Java infers the containing type from the rhino part. And, yes new rhino.Goat() would have made more sense to me too.)
So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner class via just their simple names, not via this (this in the inner class refers to the inner class instance, not the associated containing class instance):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
In the inner class, you can refer to this of the containing class as Rhino.this, and you can use this to refer to its members, e.g. Rhino.this.barry.
Local Inner Classes
A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).
Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)
If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method's this at the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simply via its name, e.g. local inner class Cat is instantiated as new Cat(), not new this.Cat() as you might expect.
Anonymous Inner Classes
An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:
new *ParentClassName*(*constructorArgs*) {*members*}
This is an expression returning a new instance of an unnamed class which extends ParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)
Alternatively, you can specify an interface to implement:
new *InterfaceName*() {*members*}
Such a declaration creates a new instance of an unnamed class which extends Object and implements InterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).
Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).
Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other than Object or which specifies its own constructor, you're stuck creating a regular named local inner class.
I don't think the real difference became clear in the above answers.
First to get the terms right:
A nested class is a class which is contained in another class at the source code level.
It is static if you declare it with the static modifier.
A non-static nested class is called inner class. (I stay with non-static nested class.)
Martin's answer is right so far. However, the actual question is: What is the purpose of declaring a nested class static or not?
You use static nested classes if you just want to keep your classes together if they belong topically together or if the nested class is exclusively used in the enclosing class. There is no semantic difference between a static nested class and every other class.
Non-static nested classes are a different beast. Similar to anonymous inner classes, such nested classes are actually closures. That means they capture their surrounding scope and their enclosing instance and make that accessible. Perhaps an example will clarify that. See this stub of a Container:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
In this case you want to have a reference from a child item to the parent container. Using a non-static nested class, this works without some work. You can access the enclosing instance of Container with the syntax Container.this.
More hardcore explanations following:
If you look at the Java bytecodes the compiler generates for an (non-static) nested class it might become even clearer:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
As you can see the compiler creates a hidden field Container this$0. This is set in the constructor which has an additional parameter of type Container to specify the enclosing instance. You can't see this parameter in the source but the compiler implicitly generates it for a nested class.
Martin's example
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
would so be compiled to a call of something like (in bytecodes)
new InnerClass(outerObject)
For the sake of completeness:
An anonymous class is a perfect example of a non-static nested class which just has no name associated with it and can't be referenced later.
I think that none of the above answers explain to you the real difference between a nested class and a static nested class in term of application design :
OverView
A nested class could be nonstatic or static and in each case is a class defined within another class. A nested class should exist only to serve is enclosing class, if a nested class is useful by other classes (not only the enclosing), should be declared as a top level class.
Difference
Nonstatic Nested class : is implicitly associated with the enclosing instance of the containing class, this means that it is possible to invoke methods and access variables of the enclosing instance. One common use of a nonstatic nested class is to define an Adapter class.
Static Nested Class : can't access enclosing class instance and invoke methods on it, so should be used when the nested class doesn't require access to an instance of the enclosing class . A common use of static nested class is to implement a components of the outer object.
Conclusion
So the main difference between the two from a design standpoint is : nonstatic nested class can access instance of the container class, while static can't.
Here is key differences and similarities between Java inner class and static nested class.
Hope it helps!
Inner class
Can access to outer class both instance and static methods and fields
Associated with instance of enclosing class so to instantiate it first needs an instance of outer class (note new keyword place):
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
Cannot define any static members itself
Cannot have Class or Interface declaration
Static nested class
Cannot access outer class instance methods or fields
Not associated with any instance of enclosing class So to instantiate it:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Similarities
Both Inner classes can access even private fields and methods of outer class
Also the Outer class have access to private fields and methods of inner classes
Both classes can have private, protected or public access modifier
Why Use Nested Classes?
According to Oracle documentation there're several reasons (full documentation):
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.
In simple terms we need nested classes primarily because Java does not provide closures.
Nested Classes are classes defined inside the body of another enclosing class. They are of two types - static and non-static.
They are treated as members of the enclosing class, hence you can specify any of the four access specifiers - private, package, protected, public. We don't have this luxury with top-level classes, which can only be declared public or package-private.
Inner classes aka Non-stack classes have access to other members of the top class, even if they are declared private while Static nested classes do not have access to other members of the top class.
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
Inner1 is our static inner class and Inner2 is our inner class which is not static. The key difference between them, you can't create an Inner2 instance without an Outer where as you can create an Inner1 object independently.
When would you use Inner class?
Think of a situation where Class A and Class B are related, Class B needs to access Class A members, and Class B is related only to Class A. Inner classes comes into the picture.
For creating an instance of inner class, you need to create an instance of your outer class.
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
or
OuterClass.Inner2 inner = new OuterClass().new Inner2();
When would you use static Inner class?
You would define a static inner class when you know that it does not have any relationship with the instance of the enclosing class/top class. If your inner class doesn't use methods or fields of the outer class, it's just a waste of space, so make it static.
For example, to create an object for the static nested class, use this syntax:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
The advantage of a static nested class is that it doesn't need an object of the containing class/top class to work. This can help you to reduce the number of objects your application creates at runtime.
I think, the convention that is generally followed is this:
static class within a top level class is a nested class
non static class within a top level class is a inner class, which further
has two more form:
local class - named classes declared inside of a block like a method or constructor body
anonymous class - unnamed classes whose instances are created in expressions and statements
However, few other points to remembers are:
Top level classes and static nested class are semantically same except that in case of static nested class it can make static reference to private static fields/methods of its Outer [parent] class and vice versa.
Inner classes have access to instance variables of the enclosing instance of the Outer [parent] class. However, not all inner classes have enclosing instances, for example inner classes in static contexts, like an anonymous class used in a static initializer block, do not.
Anonymous class by default extends the parent class or implements the parent interface and there is no further clause to extend any other class or implement any more interfaces. So,
new YourClass(){}; means class [Anonymous] extends YourClass {}
new YourInterface(){}; means class [Anonymous] implements YourInterface {}
I feel that the bigger question that remains open which one to use and when? Well that mostly depends on what scenario you are dealing with but reading the reply given by #jrudolph may help you making some decision.
Nested class: class inside class
Types:
Static nested class
Non-static nested class [Inner class]
Difference:
Non-static nested class [Inner class]
In non-static nested class object of inner class exist within object of outer class. So that data member of outer class is accessible to inner class. So to create object of inner class we must create object of outer class first.
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
Static nested class
In static nested class object of inner class don't need object of outer class, because the word "static" indicate no need to create object.
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
If you want to access x, then write the following inside method
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
The instance of the inner class is created when instance of the outer class is created. Therefore the members and methods of the inner class have access to the members and methods of the instance (object) of the outer class. When the instance of the outer class goes out of scope, also the inner class instances cease to exist.
The static nested class doesn't have a concrete instance. It's just loaded when it's used for the first time (just like the static methods). It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class.
The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class. Therefore the rule of thumb is to try to define static nested class, with as limited scope as possible (private >= class >= protected >= public), and then convert it to inner class (by removing "static" identifier) and loosen the scope, if it's really necessary.
There is a subtlety about the use of nested static classes that might be useful in certain situations.
Whereas static attributes get instantiated before the class gets instantiated via its constructor,
static attributes inside of nested static classes don't seem to get instantiated until after the
class's constructor gets invoked, or at least not until after the attributes are first referenced,
even if they are marked as 'final'.
Consider this example:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
Even though 'nested' and 'innerItem' are both declared as 'static final'. the setting
of nested.innerItem doesn't take place until after the class is instantiated (or at least
not until after the nested static item is first referenced), as you can see for yourself
by commenting and uncommenting the lines that I refer to, above. The same does not hold
true for 'outerItem'.
At least this is what I'm seeing in Java 6.0.
The terms are used interchangeably. If you want to be really pedantic about it, then you could define "nested class" to refer to a static inner class, one which has no enclosing instance. In code, you might have something like this:
public class Outer {
public class Inner {}
public static class Nested {}
}
That's not really a widely accepted definition though.
In the case of creating instance, the instance of non
static inner class is created with the reference of
object of outer class in which it is defined. This
means it have inclosing instance.
But the instance of static inner class
is created with the reference of Outer class, not with
the reference of object of outer class. This means it
have not inclosing instance.
For example:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
I don't think there is much to add here, most of the answers perfectly explain the differences between static nested class and Inner classes. However, consider the following issue when using nested classes vs inner classes.
As mention in a couple of answers inner classes can not be instantiated without and instance of their enclosing class which mean that they HOLD a pointer to the instance of their enclosing class which can lead to memory overflow or stack overflow exception due to the fact the GC will not be able to garbage collect the enclosing classes even if they are not used any more. To make this clear check the following code out:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
#Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
If you remove the comment on // inner = null; The program will out put
"I am destroyed !", but keeping this commented it will not.
The reason is that white inner instance is still referenced GC cannot collect it and because it references (has a pointer to) the outer instance it is not collected too. Having enough of these objects in your project and can run out of memory.
Compared to static inner classes which does not hold a point to inner class instance because it is not instance related but class related.
The above program can print "I am destroyed !" if you make Inner class static and instantiated with Outer.Inner i = new Outer.Inner();
Nested class is a very general term: every class which is not top level is a nested class.
An inner class is a non-static nested class.
Joseph Darcy wrote a very nice explanation about Nested, Inner, Member, and Top-Level Classes.
Targeting learner, who are novice to Java and/or Nested Classes
Nested classes can be either:
1. Static Nested classes.
2. Non Static Nested classes. (also known as Inner classes) =>Please remember this
1.Inner classes
Example:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
Inner classes are subsets of nested classes:
inner class is a specific type of nested class
inner classes are subsets of nested classes
You can say that an inner class is also a nested class, but you can NOT say that a nested class is also an inner class.
Specialty of Inner class:
instance of an inner class has access to all of the members of the outer class, even those that are marked “private”
2.Static Nested Classes:
Example:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
Case 1:Instantiating a static nested class from a non-enclosing class
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
Case 2:Instantiating a static nested class from an enclosing class
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
Specialty of Static classes:
Static inner class would only have access to the static members of the outer class, and have no access to non-static members.
Conclusion:
Question: What is the main difference between a inner class and a static nested class in Java?
Answer: just go through specifics of each class mentioned above.
I think that none of the above answers give the real example to you the difference between a nested class and a static nested class in term of application design. And the main difference between static nested class and inner class is the ability to access the outer class instance field.
Let us take a look at the two following examples.
Static nest class: An good example of using static nested classes is builder pattern (https://dzone.com/articles/design-patterns-the-builder-pattern).
For BankAccount we use a static nested class, mainly because
Static nest class instance could be created before the outer class.
In the builder pattern, the builder is a helper class which is used to create the BankAccount.
BankAccount.Builder is only associated with BankAccount. No other classes are related to BankAccount.Builder. so it is better to organize them together without using name convention.
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
Inner class: A common use of inner classes is to define an event handler.
https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
For MyClass, we use the inner class, mainly because:
Inner class MyAdapter need to access the outer class member.
In the example, MyAdapter is only associated with MyClass. No other classes are related to MyAdapter. so it is better to organize them together without using a name convention
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
Ummm… An inner class is a nested class… Do you mean anonymous class and inner class?
Edit: If you actually meant inner v.s. anonymous: an inner class is just a class defined within a class, such as:
public class A {
public class B {
}
}
…whereas an anonymous class is an extension of a class defined anonymously, so no actual "class" is defined, as in:
public class A {
}
A anon = new A() { /* You could change behavior of A here */ };
Further edit:
Wikipedia claims there is a difference in Java, but I've been working with Java for eight years, and it's the first time I heard such a distinction – not to mention there are no references there to back up the claim… Bottom line, an inner class is a class defined within a class (static or not), and nested is just another term to mean the same thing.
There is a subtle difference between static and non-static nested classes… Basically, non-static inner classes have implicit access to instance fields and methods of the enclosing class (thus they cannot be constructed in a static context, it will be a compiler error). On the other hand, static nested classes don't have implicit access to instance fields and methods and can be constructed in a static context.
Inner class and nested static class in Java both are classes declared inside another class, known as top level class in Java. In Java terminology, If you declare a nested class static, it will called nested static class in Java while non static nested class are simply referred as Inner Class.
What is Inner Class in Java?
Any class which is not a top level or declared inside another class is known as nested class and out of those nested classes, class which are declared non static are known as Inner class in Java. there are three kinds of Inner class in Java:
1) Local inner class - is declared inside a code block or method.
2) Anonymous inner class - is a class which doesn't have name to reference and initialized at same place where it gets created.
3) Member inner class - is declared as non static member of outer class.
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
#Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
What is nested static class in Java?
Nested static class is another class which is declared inside a class as member and made static. Nested static class is also declared as member of outer class and can be make private, public or protected like any other member. One of the main benefit of nested static class over inner class is that instance of nested static class is not attached to any enclosing instance of Outer class. You also don't need any instance of Outer class to create instance of nested static class in Java.
1) It can access static data members of outer class including private.
2) Static nested class cannot access non-static (instance) data member or method.
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Ref: Inner class and nested Static Class in Java with Example
A diagram
The main difference between static nested and non-static nested classes is that static nested does not have an access to non-static outer class members
I think people here should notice to Poster that : Static Nest Class just only the first inner class.
For example:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
So, summarize, static class doesn't depend which class its contains. So, they cannot in normal class. (because normal class need an instance).
When we declare static member class inside a class, it is known as top level nested class or a static nested class. It can be demonstrated as below :
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
When we declare non-static member class inside a class it is known as inner class. Inner class can be demonstrated as below :
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
The following is an example of static nested class and inner class:
OuterClass.java
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
OuterClassTest:
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here:
class OuterClass {
...
class NestedClass {
...
}
}
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
One thing that we should keep in mind is Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes only have access to other members of the enclosing class if those are static. It can not access non static members of the outer class.
As with class methods and variables, a static nested class is associated with its outer class.
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
Why we use nested classes
It is a way of logically grouping classes that are only used in one place.
It increases encapsulation.
It can lead to more readable and maintainable code.
Source: The Java™ Tutorials - Nested Classes
First of all There is no such class called Static class.The Static modifier use with inner class (called as Nested Class) says that it is a static member of Outer Class which means we can access it as with other static members and without having any instance of Outer class. (Which is benefit of static originally.)
Difference between using Nested class and regular Inner class is:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
First We can to instantiate Outerclass then we Can access Inner.
But if Class is Nested then syntax is:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
Which uses the static Syntax as normal implementation of static keyword.
Another use case for nested classes, in addition to those that already have been mentioned, is when the nested class has methods that should only be accessible from the outer class. This is possible because the outer class has access to the private constructors, fields and methods of the nested class.
In the example below, the Bank can issue a Bank.CreditCard, which has a private constructor, and can change a credit card's limit according to the current bank policy using the private setLimit(...) instance method of Bank.CreditCard. (A direct field access to the instance variable limit would also work in this case). From any other class only the public methods of Bank.CreditCard are accessible.
public class Bank {
// maximum limit as per current bank policy
// is subject to change
private int maxLimit = 7000;
// ------- PUBLIC METHODS ---------
public CreditCard issueCard(
final String firstName,
final String lastName
) {
final String number = this.generateNumber();
final int expiryDate = this.generateExpiryDate();
final int CVV = this.generateCVV();
return new CreditCard(firstName, lastName, number, expiryDate, CVV);
}
public boolean setLimit(
final CreditCard creditCard,
final int limit
) {
if (limit <= this.maxLimit) { // check against current bank policy limit
creditCard.setLimit(limit); // access private method Bank.CreditCard.setLimit(int)
return true;
}
return false;
}
// ------- PRIVATE METHODS ---------
private String generateNumber() {
return "1234-5678-9101-1123"; // the numbers should be unique for each card
}
private int generateExpiryDate() {
return 202405; // date is YYYY=2024, MM=05
}
private int generateCVV() {
return 123; // is in real-life less predictable
}
// ------- PUBLIC STATIC NESTED CLASS ---------
public static final class CreditCard {
private final String firstName;
private final String lastName;
private final String number;
private final int expiryDate;
private final int CVV;
private int balance;
private int limit = 100; // default limit
// the constructor is final but is accessible from outer class
private CreditCard(
final String firstName,
final String lastName,
final String number,
final int expiryDate,
final int CVV
) {
this.firstName = firstName;
this.lastName = lastName;
this.number = number;
this.expiryDate = expiryDate;
this.CVV = CVV;
}
// ------- PUBLIC METHODS ---------
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public String getNumber() {
return this.number;
}
public int getExpiryDate() {
return this.expiryDate;
}
// returns true if financial transaction is successful
// otherwise false
public boolean charge(final int amount) {
final int newBalance = this.balance - amount;
if (newBalance < -this.limit) {
return false;
}
this.balance = newBalance;
return true;
}
// ------- PRIVATE METHODS ---------
private int getCVV() {
return this.CVV;
}
private int getBalance() {
return this.balance;
}
private void setBalance(final int balance) {
this.balance = balance;
}
private int getLimit() {
return limit;
}
private void setLimit(final int limit) {
this.limit = limit;
}
}
}
Static nested classes access PRIVATE class-level static variables of the class they are defined in. That can be huge from an architectural standpoint (i.e. Service Locator pattern employing nested static helper classes in Services), and may help OP see why they exist along with inner classes.
The difference is that a nested class declaration that is also static can be instantiated outside of the enclosing class.
When you have a nested class declaration that is not static, also known as an inner class, Java won't let you instantiate it except via the enclosing class. The object created out of the inner class is linked to the object created from the outer class, so the inner class can reference the fields of the outer.
But if it's static, then the link does not exist, the outer fields cannot be accessed (except via an ordinary reference like any other object) and you can therefore instantiate the nested class by itself.
I have illustrated various possible correct and error scenario which can occur in java code.
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}
What is the main difference between an inner class and a static nested class in Java? Does design / implementation play a role in choosing one of these?
From the Java Tutorial:
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.
Static nested classes are accessed using the enclosing class name:
OuterClass.StaticNestedClass
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:
class OuterClass {
...
class InnerClass {
...
}
}
An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
see: Java Tutorial - Nested Classes
For completeness note that there is also such a thing as an inner class without an enclosing instance:
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.
The Java tutorial says:
Terminology: Nested classes are
divided into two categories: static
and non-static. Nested classes that
are declared static are simply called
static nested classes. Non-static
nested classes are called inner
classes.
In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, but I'll use the correct term "nested class" which covers both inner and static.
Classes can be nested ad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.
There are three reasons you might create a nested class:
organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
access: nested classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of nested class, whether inner or static).
convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context
There are four kinds of nested class in Java. In brief, they are:
static class: declared as a static member of another class
inner class: declared as an instance member of another class
local inner class: declared inside an instance method of another class
anonymous inner class: like a local inner class, but written as an expression which returns a one-off object
Let me elaborate in more details.
Static Classes
Static classes are the easiest kind to understand because they have nothing to do with instances of the containing class.
A static class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace, e.g. the class Goat declared as a static member of class Rhino in the package pizza is known by the name pizza.Rhino.Goat.
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
Frankly, static classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static class feature to exist.
Inner Classes
An inner class is a class declared as a non-static member of another class:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
Like with a static class, the inner class is known as qualified by its containing class name, pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an inner class is tied to a particular instance of its containing class: above, the Goat created in jerry, is implicitly tied to the Rhino instance this in jerry. Otherwise, we make the associated Rhino instance explicit when we instantiate Goat:
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(Notice you refer to the inner type as just Goat in the weird new syntax: Java infers the containing type from the rhino part. And, yes new rhino.Goat() would have made more sense to me too.)
So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner class via just their simple names, not via this (this in the inner class refers to the inner class instance, not the associated containing class instance):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
In the inner class, you can refer to this of the containing class as Rhino.this, and you can use this to refer to its members, e.g. Rhino.this.barry.
Local Inner Classes
A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).
Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)
If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method's this at the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simply via its name, e.g. local inner class Cat is instantiated as new Cat(), not new this.Cat() as you might expect.
Anonymous Inner Classes
An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:
new *ParentClassName*(*constructorArgs*) {*members*}
This is an expression returning a new instance of an unnamed class which extends ParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)
Alternatively, you can specify an interface to implement:
new *InterfaceName*() {*members*}
Such a declaration creates a new instance of an unnamed class which extends Object and implements InterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).
Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).
Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other than Object or which specifies its own constructor, you're stuck creating a regular named local inner class.
I don't think the real difference became clear in the above answers.
First to get the terms right:
A nested class is a class which is contained in another class at the source code level.
It is static if you declare it with the static modifier.
A non-static nested class is called inner class. (I stay with non-static nested class.)
Martin's answer is right so far. However, the actual question is: What is the purpose of declaring a nested class static or not?
You use static nested classes if you just want to keep your classes together if they belong topically together or if the nested class is exclusively used in the enclosing class. There is no semantic difference between a static nested class and every other class.
Non-static nested classes are a different beast. Similar to anonymous inner classes, such nested classes are actually closures. That means they capture their surrounding scope and their enclosing instance and make that accessible. Perhaps an example will clarify that. See this stub of a Container:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
In this case you want to have a reference from a child item to the parent container. Using a non-static nested class, this works without some work. You can access the enclosing instance of Container with the syntax Container.this.
More hardcore explanations following:
If you look at the Java bytecodes the compiler generates for an (non-static) nested class it might become even clearer:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
As you can see the compiler creates a hidden field Container this$0. This is set in the constructor which has an additional parameter of type Container to specify the enclosing instance. You can't see this parameter in the source but the compiler implicitly generates it for a nested class.
Martin's example
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
would so be compiled to a call of something like (in bytecodes)
new InnerClass(outerObject)
For the sake of completeness:
An anonymous class is a perfect example of a non-static nested class which just has no name associated with it and can't be referenced later.
I think that none of the above answers explain to you the real difference between a nested class and a static nested class in term of application design :
OverView
A nested class could be nonstatic or static and in each case is a class defined within another class. A nested class should exist only to serve is enclosing class, if a nested class is useful by other classes (not only the enclosing), should be declared as a top level class.
Difference
Nonstatic Nested class : is implicitly associated with the enclosing instance of the containing class, this means that it is possible to invoke methods and access variables of the enclosing instance. One common use of a nonstatic nested class is to define an Adapter class.
Static Nested Class : can't access enclosing class instance and invoke methods on it, so should be used when the nested class doesn't require access to an instance of the enclosing class . A common use of static nested class is to implement a components of the outer object.
Conclusion
So the main difference between the two from a design standpoint is : nonstatic nested class can access instance of the container class, while static can't.
Here is key differences and similarities between Java inner class and static nested class.
Hope it helps!
Inner class
Can access to outer class both instance and static methods and fields
Associated with instance of enclosing class so to instantiate it first needs an instance of outer class (note new keyword place):
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
Cannot define any static members itself
Cannot have Class or Interface declaration
Static nested class
Cannot access outer class instance methods or fields
Not associated with any instance of enclosing class So to instantiate it:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Similarities
Both Inner classes can access even private fields and methods of outer class
Also the Outer class have access to private fields and methods of inner classes
Both classes can have private, protected or public access modifier
Why Use Nested Classes?
According to Oracle documentation there're several reasons (full documentation):
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.
In simple terms we need nested classes primarily because Java does not provide closures.
Nested Classes are classes defined inside the body of another enclosing class. They are of two types - static and non-static.
They are treated as members of the enclosing class, hence you can specify any of the four access specifiers - private, package, protected, public. We don't have this luxury with top-level classes, which can only be declared public or package-private.
Inner classes aka Non-stack classes have access to other members of the top class, even if they are declared private while Static nested classes do not have access to other members of the top class.
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
Inner1 is our static inner class and Inner2 is our inner class which is not static. The key difference between them, you can't create an Inner2 instance without an Outer where as you can create an Inner1 object independently.
When would you use Inner class?
Think of a situation where Class A and Class B are related, Class B needs to access Class A members, and Class B is related only to Class A. Inner classes comes into the picture.
For creating an instance of inner class, you need to create an instance of your outer class.
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
or
OuterClass.Inner2 inner = new OuterClass().new Inner2();
When would you use static Inner class?
You would define a static inner class when you know that it does not have any relationship with the instance of the enclosing class/top class. If your inner class doesn't use methods or fields of the outer class, it's just a waste of space, so make it static.
For example, to create an object for the static nested class, use this syntax:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
The advantage of a static nested class is that it doesn't need an object of the containing class/top class to work. This can help you to reduce the number of objects your application creates at runtime.
I think, the convention that is generally followed is this:
static class within a top level class is a nested class
non static class within a top level class is a inner class, which further
has two more form:
local class - named classes declared inside of a block like a method or constructor body
anonymous class - unnamed classes whose instances are created in expressions and statements
However, few other points to remembers are:
Top level classes and static nested class are semantically same except that in case of static nested class it can make static reference to private static fields/methods of its Outer [parent] class and vice versa.
Inner classes have access to instance variables of the enclosing instance of the Outer [parent] class. However, not all inner classes have enclosing instances, for example inner classes in static contexts, like an anonymous class used in a static initializer block, do not.
Anonymous class by default extends the parent class or implements the parent interface and there is no further clause to extend any other class or implement any more interfaces. So,
new YourClass(){}; means class [Anonymous] extends YourClass {}
new YourInterface(){}; means class [Anonymous] implements YourInterface {}
I feel that the bigger question that remains open which one to use and when? Well that mostly depends on what scenario you are dealing with but reading the reply given by #jrudolph may help you making some decision.
Nested class: class inside class
Types:
Static nested class
Non-static nested class [Inner class]
Difference:
Non-static nested class [Inner class]
In non-static nested class object of inner class exist within object of outer class. So that data member of outer class is accessible to inner class. So to create object of inner class we must create object of outer class first.
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
Static nested class
In static nested class object of inner class don't need object of outer class, because the word "static" indicate no need to create object.
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
If you want to access x, then write the following inside method
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
The instance of the inner class is created when instance of the outer class is created. Therefore the members and methods of the inner class have access to the members and methods of the instance (object) of the outer class. When the instance of the outer class goes out of scope, also the inner class instances cease to exist.
The static nested class doesn't have a concrete instance. It's just loaded when it's used for the first time (just like the static methods). It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class.
The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class. Therefore the rule of thumb is to try to define static nested class, with as limited scope as possible (private >= class >= protected >= public), and then convert it to inner class (by removing "static" identifier) and loosen the scope, if it's really necessary.
There is a subtlety about the use of nested static classes that might be useful in certain situations.
Whereas static attributes get instantiated before the class gets instantiated via its constructor,
static attributes inside of nested static classes don't seem to get instantiated until after the
class's constructor gets invoked, or at least not until after the attributes are first referenced,
even if they are marked as 'final'.
Consider this example:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
Even though 'nested' and 'innerItem' are both declared as 'static final'. the setting
of nested.innerItem doesn't take place until after the class is instantiated (or at least
not until after the nested static item is first referenced), as you can see for yourself
by commenting and uncommenting the lines that I refer to, above. The same does not hold
true for 'outerItem'.
At least this is what I'm seeing in Java 6.0.
The terms are used interchangeably. If you want to be really pedantic about it, then you could define "nested class" to refer to a static inner class, one which has no enclosing instance. In code, you might have something like this:
public class Outer {
public class Inner {}
public static class Nested {}
}
That's not really a widely accepted definition though.
In the case of creating instance, the instance of non
static inner class is created with the reference of
object of outer class in which it is defined. This
means it have inclosing instance.
But the instance of static inner class
is created with the reference of Outer class, not with
the reference of object of outer class. This means it
have not inclosing instance.
For example:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
I don't think there is much to add here, most of the answers perfectly explain the differences between static nested class and Inner classes. However, consider the following issue when using nested classes vs inner classes.
As mention in a couple of answers inner classes can not be instantiated without and instance of their enclosing class which mean that they HOLD a pointer to the instance of their enclosing class which can lead to memory overflow or stack overflow exception due to the fact the GC will not be able to garbage collect the enclosing classes even if they are not used any more. To make this clear check the following code out:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
#Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
If you remove the comment on // inner = null; The program will out put
"I am destroyed !", but keeping this commented it will not.
The reason is that white inner instance is still referenced GC cannot collect it and because it references (has a pointer to) the outer instance it is not collected too. Having enough of these objects in your project and can run out of memory.
Compared to static inner classes which does not hold a point to inner class instance because it is not instance related but class related.
The above program can print "I am destroyed !" if you make Inner class static and instantiated with Outer.Inner i = new Outer.Inner();
Nested class is a very general term: every class which is not top level is a nested class.
An inner class is a non-static nested class.
Joseph Darcy wrote a very nice explanation about Nested, Inner, Member, and Top-Level Classes.
Targeting learner, who are novice to Java and/or Nested Classes
Nested classes can be either:
1. Static Nested classes.
2. Non Static Nested classes. (also known as Inner classes) =>Please remember this
1.Inner classes
Example:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
Inner classes are subsets of nested classes:
inner class is a specific type of nested class
inner classes are subsets of nested classes
You can say that an inner class is also a nested class, but you can NOT say that a nested class is also an inner class.
Specialty of Inner class:
instance of an inner class has access to all of the members of the outer class, even those that are marked “private”
2.Static Nested Classes:
Example:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
Case 1:Instantiating a static nested class from a non-enclosing class
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
Case 2:Instantiating a static nested class from an enclosing class
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
Specialty of Static classes:
Static inner class would only have access to the static members of the outer class, and have no access to non-static members.
Conclusion:
Question: What is the main difference between a inner class and a static nested class in Java?
Answer: just go through specifics of each class mentioned above.
I think that none of the above answers give the real example to you the difference between a nested class and a static nested class in term of application design. And the main difference between static nested class and inner class is the ability to access the outer class instance field.
Let us take a look at the two following examples.
Static nest class: An good example of using static nested classes is builder pattern (https://dzone.com/articles/design-patterns-the-builder-pattern).
For BankAccount we use a static nested class, mainly because
Static nest class instance could be created before the outer class.
In the builder pattern, the builder is a helper class which is used to create the BankAccount.
BankAccount.Builder is only associated with BankAccount. No other classes are related to BankAccount.Builder. so it is better to organize them together without using name convention.
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
Inner class: A common use of inner classes is to define an event handler.
https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
For MyClass, we use the inner class, mainly because:
Inner class MyAdapter need to access the outer class member.
In the example, MyAdapter is only associated with MyClass. No other classes are related to MyAdapter. so it is better to organize them together without using a name convention
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
Ummm… An inner class is a nested class… Do you mean anonymous class and inner class?
Edit: If you actually meant inner v.s. anonymous: an inner class is just a class defined within a class, such as:
public class A {
public class B {
}
}
…whereas an anonymous class is an extension of a class defined anonymously, so no actual "class" is defined, as in:
public class A {
}
A anon = new A() { /* You could change behavior of A here */ };
Further edit:
Wikipedia claims there is a difference in Java, but I've been working with Java for eight years, and it's the first time I heard such a distinction – not to mention there are no references there to back up the claim… Bottom line, an inner class is a class defined within a class (static or not), and nested is just another term to mean the same thing.
There is a subtle difference between static and non-static nested classes… Basically, non-static inner classes have implicit access to instance fields and methods of the enclosing class (thus they cannot be constructed in a static context, it will be a compiler error). On the other hand, static nested classes don't have implicit access to instance fields and methods and can be constructed in a static context.
Inner class and nested static class in Java both are classes declared inside another class, known as top level class in Java. In Java terminology, If you declare a nested class static, it will called nested static class in Java while non static nested class are simply referred as Inner Class.
What is Inner Class in Java?
Any class which is not a top level or declared inside another class is known as nested class and out of those nested classes, class which are declared non static are known as Inner class in Java. there are three kinds of Inner class in Java:
1) Local inner class - is declared inside a code block or method.
2) Anonymous inner class - is a class which doesn't have name to reference and initialized at same place where it gets created.
3) Member inner class - is declared as non static member of outer class.
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
#Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
What is nested static class in Java?
Nested static class is another class which is declared inside a class as member and made static. Nested static class is also declared as member of outer class and can be make private, public or protected like any other member. One of the main benefit of nested static class over inner class is that instance of nested static class is not attached to any enclosing instance of Outer class. You also don't need any instance of Outer class to create instance of nested static class in Java.
1) It can access static data members of outer class including private.
2) Static nested class cannot access non-static (instance) data member or method.
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Ref: Inner class and nested Static Class in Java with Example
A diagram
The main difference between static nested and non-static nested classes is that static nested does not have an access to non-static outer class members
I think people here should notice to Poster that : Static Nest Class just only the first inner class.
For example:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
So, summarize, static class doesn't depend which class its contains. So, they cannot in normal class. (because normal class need an instance).
When we declare static member class inside a class, it is known as top level nested class or a static nested class. It can be demonstrated as below :
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
When we declare non-static member class inside a class it is known as inner class. Inner class can be demonstrated as below :
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
The following is an example of static nested class and inner class:
OuterClass.java
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
OuterClassTest:
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here:
class OuterClass {
...
class NestedClass {
...
}
}
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
One thing that we should keep in mind is Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes only have access to other members of the enclosing class if those are static. It can not access non static members of the outer class.
As with class methods and variables, a static nested class is associated with its outer class.
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
Why we use nested classes
It is a way of logically grouping classes that are only used in one place.
It increases encapsulation.
It can lead to more readable and maintainable code.
Source: The Java™ Tutorials - Nested Classes
First of all There is no such class called Static class.The Static modifier use with inner class (called as Nested Class) says that it is a static member of Outer Class which means we can access it as with other static members and without having any instance of Outer class. (Which is benefit of static originally.)
Difference between using Nested class and regular Inner class is:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
First We can to instantiate Outerclass then we Can access Inner.
But if Class is Nested then syntax is:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
Which uses the static Syntax as normal implementation of static keyword.
Another use case for nested classes, in addition to those that already have been mentioned, is when the nested class has methods that should only be accessible from the outer class. This is possible because the outer class has access to the private constructors, fields and methods of the nested class.
In the example below, the Bank can issue a Bank.CreditCard, which has a private constructor, and can change a credit card's limit according to the current bank policy using the private setLimit(...) instance method of Bank.CreditCard. (A direct field access to the instance variable limit would also work in this case). From any other class only the public methods of Bank.CreditCard are accessible.
public class Bank {
// maximum limit as per current bank policy
// is subject to change
private int maxLimit = 7000;
// ------- PUBLIC METHODS ---------
public CreditCard issueCard(
final String firstName,
final String lastName
) {
final String number = this.generateNumber();
final int expiryDate = this.generateExpiryDate();
final int CVV = this.generateCVV();
return new CreditCard(firstName, lastName, number, expiryDate, CVV);
}
public boolean setLimit(
final CreditCard creditCard,
final int limit
) {
if (limit <= this.maxLimit) { // check against current bank policy limit
creditCard.setLimit(limit); // access private method Bank.CreditCard.setLimit(int)
return true;
}
return false;
}
// ------- PRIVATE METHODS ---------
private String generateNumber() {
return "1234-5678-9101-1123"; // the numbers should be unique for each card
}
private int generateExpiryDate() {
return 202405; // date is YYYY=2024, MM=05
}
private int generateCVV() {
return 123; // is in real-life less predictable
}
// ------- PUBLIC STATIC NESTED CLASS ---------
public static final class CreditCard {
private final String firstName;
private final String lastName;
private final String number;
private final int expiryDate;
private final int CVV;
private int balance;
private int limit = 100; // default limit
// the constructor is final but is accessible from outer class
private CreditCard(
final String firstName,
final String lastName,
final String number,
final int expiryDate,
final int CVV
) {
this.firstName = firstName;
this.lastName = lastName;
this.number = number;
this.expiryDate = expiryDate;
this.CVV = CVV;
}
// ------- PUBLIC METHODS ---------
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public String getNumber() {
return this.number;
}
public int getExpiryDate() {
return this.expiryDate;
}
// returns true if financial transaction is successful
// otherwise false
public boolean charge(final int amount) {
final int newBalance = this.balance - amount;
if (newBalance < -this.limit) {
return false;
}
this.balance = newBalance;
return true;
}
// ------- PRIVATE METHODS ---------
private int getCVV() {
return this.CVV;
}
private int getBalance() {
return this.balance;
}
private void setBalance(final int balance) {
this.balance = balance;
}
private int getLimit() {
return limit;
}
private void setLimit(final int limit) {
this.limit = limit;
}
}
}
Static nested classes access PRIVATE class-level static variables of the class they are defined in. That can be huge from an architectural standpoint (i.e. Service Locator pattern employing nested static helper classes in Services), and may help OP see why they exist along with inner classes.
The difference is that a nested class declaration that is also static can be instantiated outside of the enclosing class.
When you have a nested class declaration that is not static, also known as an inner class, Java won't let you instantiate it except via the enclosing class. The object created out of the inner class is linked to the object created from the outer class, so the inner class can reference the fields of the outer.
But if it's static, then the link does not exist, the outer fields cannot be accessed (except via an ordinary reference like any other object) and you can therefore instantiate the nested class by itself.
I have illustrated various possible correct and error scenario which can occur in java code.
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}
I would like to understand a strange behavior I faced dealing with anonymous classes.
I have a class that calls a protected method inside its constructor (I know, poor design but that's another story...)
public class A {
public A() {
init();
}
protected void init() {}
}
then I have another class that extends A and overrides init().
public class B extends A {
int value;
public B(int i) {
value = i;
}
protected void init() {
System.out.println("value="+value);
}
}
If I code
B b = new B(10);
I get
> value=0
and that's expected because the constructor of the super class is invoked before the B ctor and then value is still.
But when using an anonymous class like this
class C {
public static void main (String[] args) {
final int avalue = Integer.parsetInt(args[0]);
A a = new A() {
void init() { System.out.println("value="+avalue); }
}
}
}
I would expect to get value=0 because this should be more or less equal to class B: the compiler automatically creates a new class C$1 that extends A and creates instance variables to store local variables referenced in the methods of the anonymous class, simulating a closure etc...
But when you run this, I got
> java -cp . C 42
> value=42
Initially I was thinking that this was due to the fact that I was using java 8, and maybe, when introducing lamdbas, they changed the way anonymous classes are implemented under the hood (you no longer need for final), but I tried with java 7 also and got the same result...
Actually, looking at the byte code with javap, I can see that B is
> javap -c B
Compiled from "B.java"
public class B extends A {
int value;
public B(int);
Code:
0: aload_0
1: invokespecial #1 // Method A."<init>":()V
4: aload_0
5: iload_1
6: putfield #2 // Field value:I
9: return
...
while for C$1:
> javap -c C\$1
Compiled from "C.java"
final class C$1 extends A {
final int val$v;
C$1(int);
Code:
0: aload_0
1: iload_1
2: putfield #1 // Field val$v:I
5: aload_0
6: invokespecial #2 // Method A."<init>":()V
9: return
....
Could someone tell me why this difference?
Is there a way to replicate the behavior of the anonymous class using "normal" classes?
EDIT:
to clarify the question: why does the initialization of the anonymous classes break the rules for initializing of any other class (where super constructor is invoked before setting any other variable)?
Or, is there a way to set instance variable in B class before inovking super constructor?
This question applies to all inner classes, not just anon classes. (Anon classes are inner classes)
JLS does not dictates how an inner class body accesses outer local variable; it only specifies that the local variables are effectively final, and definitely assigned before the inner class body. Therefore, it stands to reason that the inner class must see the definitely assigned value of the local variable.
JLS does not specify exactly how the inner class sees that value; it is up to the compiler to use whatever trick (that is possible on the bytecode level) to achieve that effect. In particular, this issue is completely unrelated to constructors (as far as the language is concerned).
A similar issue is how an inner class accesses the outer instance. This is a bit more complicated, and it does have something to do with constructors. Nevertheless, JLS still does not dictate how it is achieved by the compiler; the section contains a comment that "... compiler can represent the immediately enclosing instance how ever it wishes. There is no need for the Java programming language to ... "
From JMM point of view, this under-specification might be a problem; it is unclear how writes were done in relation to reads in inner class. It is reasonable to assume that, a write is done on a synthetic variable, which is before (in programming order) the new InnerClass() action; the inner class reads the synthetic variable to see the outer local variable or the enclosing instance.
Is there a way to replicate the behavior of the anonymous class using "normal" classes?
You may arrange the "normal" class as outer-inner class
public class B0
{
int value;
public B0(int i){ value=i; }
public class B extends A
{
protected void init()
{
System.out.println("value="+value);
}
}
}
It will be used like this, which prints 10
new B0(10).new B();
A convenience factory method can be added to hide the syntax ugliness
newB(10);
public static B0.B newB(int arg){ return new B0(arg).new B(); }
So we split our class into 2 parts; the outer part is executed even before the super constructor. This is useful in some cases. (another example)
( inner anonymous access local variable enclosing instance effective final super constructor)
Your anonymous class instance behaves differently than your first code snippet since you are using a local variable whose value is initialized before the anonymous class instance is created.
You can get a similar behavior to the first snippet with an anonymous class instance if you use an instance variable in the anonymous class :
class C {
public static void main (String[] args) {
A a = new A() {
int avalue = 10;
void init() { System.out.println("value="+avalue); }
}
}
}
This will print
value=0
since init() is executed by A's constructor before avalue is initialized.
The variable capture in anonymous classes is allowed to break the rules of normal constructors (super constructor call must be the first statement) because this law is only enforced by the compiler. The JVM allows any bytecode to be ran before invoking the super constructor, which is utilized by the compiler itself (it breaks it's own rules!) for anonymous classes.
You can mimic the behavior either with inner classes as shown in bayou.io's answer, or you can use an anonymous in a static B factory method:
public class B extends A
{
public static B create(int value)
{
return new B() {
void init() { System.out.println("value="+value);
};
}
}
The limitation is actually rather pointless and can be annoying in some situations:
class A
{
private int len;
public A(String s)
{
this.len = s.length();
}
}
class B extends A
{
private String complexString;
public B(int i, double d)
{
super(computeComplexString(i, d));
this.complexString = computeComplexString(i, d);
}
private static String computeComplexString(int i, double d)
{
// some code that takes a long time
}
}
In this example, you have to do the computeComplexString computation twice, because there is no way to both pass it to the super constructor and store it in an instance variable.
The two examples are not related.
In the B example:
protected void init() {
System.out.println("value="+value);
}
the value being printed is the value field of the instance of B.
In the anonymous example:
final int avalue = Integer.parsetInt(args[0]);
A a = new A() {
void init() { System.out.println("value="+avalue); }
}
the value being printed is the local variable avalue of the main() method.
public class PrivateOverride {
private void f() {
System.out.println("private f()");
}
}
public class Derived extends PrivateOverride {
public void f() { //this method is never run.
System.out.println("public f()");
}
}
public static void main(String[] args) {
// instantiate Derived and assign it to
// object po of type PrivateOverride.
PrivateOverride po = new Derived();
// invoke method f of object po. It
// chooses to run the private method of PrivateOveride
// instead of Derived
po.f();
}
}
So, the output of this code is private f(). Now, the question arises to my mind: how can po which is an object of Derived Class call a private method of PrivateOverride which is its base class?
Because you defined the main method in PrivateOverride class. If you put the main method in Derived class, it would not compile, because .f() would not be visible there.
po.f() call in PrivateOverride class is not a polymorphism, because the f() in PrivateOverride class is private, so f() in Derived class is not overriden.
I do not really see the problem. That method is called ""within"" the class, this is pretty much expected.
This method is not overidden at all, instead it is shadowed by another one.
Methods in Java are dispatched depending on the static type of the receiver, which in this case is a PrivateOverride. Do not be confused by the fact that the po variable, by examining the code, can only hold a Derived instance at that line: only the declaration matters when available methods are searched.
And, by the way, the call to f() is not even translated into a virtual call in the final bytecode, because when the compiler looks for the potentially applicable methods in the class PrivateOverride, it only finds Object methods and the f() definition, which is only visible because the main() method is defined in PrivateOverride itself (see JLS 15.12)
I just went through the byte code of the compiled version of the above class and got the invokespecial Opcode. This Opcode was enough to tell the reason why the actual output is obvious. Invokespecial is used in three situations in which an instance method must be invoked based on the type of the reference, not on the class of the object. The three situations are:
1)invocation of instance initialization () methods
2)invocation of private methods
3)invocation of methods using the super keyword
Above example lies within the second scenario where we have invocation of private methods. So the method got invoked based on the the type of reference i.e PrivateOverride rather than type of class i.e Derived
So now the question arises why invokespecial? We have other Opcode like invokevirtual which gets invoked for method on the basis of classtype rather than reference type. So lets discuss why invokespecial Opcode is used for private methods. But we should know the difference between invokevirtual and invokespecial. Invokespecial differs from invokevirtual primarily in that invokespecial selects a method based on the type of the reference rather than the class of the object. In other words, it does static binding instead of dynamic binding. In each of the three situations where invokespecial is used, dynamic binding wouldn't yield the desired result.
When a method is invoked the JVM has to figure out what piece of code to execute: sometimes this is done at runtime (e.g. when overriding methods); sometimes this is done at compile time (e.g. when overloading methods). Once the JVM resolves what bit of code it is executing the actual instance that you are referring to isn't really any more significant than any other parameter.
The example code given sets up a scenario that may look like method overriding but isn't, so the method ends up getting bound at compile time. The private visibility modifier is not violated because the invocation doesn't touch any of Derived's code.
Looking at the bytecode (which the Java code is compiled to via javac) is instructive -
Say we slightly modify the original code to:
public class PrivateOverride {
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
Derived d = new Derived();
d.f();
}
}
class Derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
The main method compiles to (edited for brevity):
public static main([Ljava/lang/String;)V
NEW Derived
DUP
INVOKESPECIAL Derived.<init>()V
ASTORE 1
ALOAD 1
INVOKESPECIAL PrivateOverride.f()V
NEW Derived
DUP
INVOKESPECIAL Derived.<init>()V
ASTORE 2
ALOAD 2
INVOKEVIRTUAL Derived.f()V
RETURN
Notice that in each case the method is invoked on the compile time type. Notice also that the second call of f() uses the INVOKEVIRTUAL instruction. This is what tells the JVM to check the runtime type and decide what to call based on that.
It behaves this way because that is how the JVM was defined to behave in those cases.
The hard part is understanding what is going on and why.
You invoked the private method from within the class in which it was private. So the trojan horse is inside the castle, he can fiddle with the private variables. Take the trojan horse out of the castle and the private method is no longer visible.
This example might clear things up, Consider this program:
public class Bicycle {
private void getCost() {
System.out.println("200");
}
public static void main(String[] args) {
Bicycle ACME_bike = new ACME_bike();
ACME_bike.getCost();
Bicycle mybike = new Bicycle();
mybike.getCost();
ACME_bike acme_bike = new ACME_bike();
acme_bike.getCost();
//ACME_bike foobar = new Bicycle(); //Syntax error: Type mismatch:
//cannot convert from
//Bicycle to ACME_bike
}
}
class ACME_bike extends Bicycle {
public void getCost(){
System.out.println("700");
}
}
This program prints:
200
200
700
If you change the access modifier of getCost within Bicycle to public, protected, or package private(no modifier), Then it prints this:
700
200
700
There are four visibility levels in Java, package-level (implied by not using any visibility), public (everyone can call this), private (only I, and internal classes that see my functions as global, can call this), and protected (I, and any subclass, can call this).
You can either make your second class an internal class and then you don't override but simply call the function as if it's global (as far as the internal class is concerned), but then you can't really create instances wherever you want because it's a class that can be used exclusively by the owner (so if you want to use it elsewhere, the owner would need to be a factory and return it as if it's the base class) or you can make the method protected, and then the extending class can call the method.
I have the following Java file:
class Outer {
class Inner { public int foo; }
class InnerChild extends Inner {}
}
I compiled then disassembled the file using this command:
javac test.java && javap -p -c Outer Outer.Inner Outer.InnerChild
This is the output:
Compiled from "test.java"
class Outer {
Outer();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
}
Compiled from "test.java"
class Outer$Inner {
public int foo;
final Outer this$0;
Outer$Inner(Outer);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LOuter;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
}
Compiled from "test.java"
class Outer$InnerChild extends Outer$Inner {
final Outer this$0;
Outer$InnerChild(Outer);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LOuter;
5: aload_0
6: aload_1
7: invokespecial #2 // Method Outer$Inner."<init>":(LOuter;)V
10: return
}
The first inner class has its this$0 field, pointing to the instance of Outer. That's fine. The second inner class, which extends the first, has a duplicate field of the same name, which it initializes before calling the super class's constructor with the same value.
The purpose of the int foo field above is just to confirm that inherited fields from the superclass do not show up in the javap output of a child class's dissassembly.
The first this$0 field is not private, so InnerChild should be able to use it. The extra field just seems to waste memory. (I first discovered it using a memory analysis tool.) What is its purpose and is there a way I can get rid of it?
The two classes may not be inner classes of the same class (if you had a complex hierarchy), so there does exist cases where the two references would be different.
For example:
class Outer {
class InnerOne {
}
class Wrapper {
class InnerTwo extends InnerOne {
}
}
}
InnerTwo has a reference to Wrapper, InnerOne has a reference to Outer.
You can try it with the following Java code:
public class Main{
static class Outer {
class InnerOne {
String getOuters() {
return this+"->"+Outer.this;
}
}
class Wrapper {
class InnerTwo extends InnerOne {
String getOuters() {
return this+"->"+Wrapper.this+"->"+super.getOuters();
}
}
}
}
public static void main(String[] args){
Outer o = new Outer();
Outer.Wrapper w = o.new Wrapper();
Outer.Wrapper.InnerTwo i2 = w.new InnerTwo();
System.out.println(w);
System.out.println(i2);
System.out.println(i2.getOuters());
}
}
I've set it up as a snippet on tryjava8: http://www.tryjava8.com/app/snippets/52c23585e4b00bdc99e8a96c
Main$Outer$Wrapper#1448139f
Main$Outer$Wrapper$InnerTwo#1f7f1d70
Main$Outer$Wrapper$InnerTwo#1f7f1d70->Main$Outer$Wrapper#1448139f->Main$Outer$Wrapper$InnerTwo#1f7f1d70->Main$Outer#6945af95
You can see that the two getOuters() calls are referencing a different object.
#TimB's answer is interesting because it shows how subtle the outer class references can be, but I think I've found a simpler case:
class Outer {
class Inner {}
}
class OuterChild extends Outer {
class InnerChild extends Inner {}
}
In this case, InnerChild's this$0 reference is of type Child rather than Outer, so it can't use the this$0 field from its parent because even though the value is identical, it's the wrong type. I suspect this is the origin of the extra field. Still, I believe Javac could eliminate it when InnerChild and Inner have the same outer class, because then the field has the same value and the same type. (I would report it as a bug but they never fix them, and if it's not a bug they don't give feedback anyway.)
I've finally figured out some decent workarounds though.
The plainest workaround (which took me far too long to think of) is to make the member classes "static", and store the ref to Outer as an explicit field on the base class:
class Outer {
static class Inner {
protected final Outer outer;
Inner(Outer outer) {
this.outer = outer;
}
}
static class InnerChild extends Inner {
InnerChild(Outer outer) {
super(outer);
}
}
}
Through the outer field, both Inner and InnerChild can access instance members of Outer (even private ones). This is equivalent to the code that I think Javac should generate anyway for the original non-static classes.
Second workaround: I discovered by complete accident that the child class of a non-static member class may be static! All these years in Java I never knew about the obscure syntax which makes this work... it is not in the official tutorials. I would have always believed it impossible except that Eclipse automatically filled in the constructor for me. (However, Eclipse doesn't seem to want to repeat this magic... I'm so confused.) Anyway, apparently it's called a "qualified superclass constructor invocation", and it's buried in the JLS in section 8.8.7.1.
class Outer {
class Inner {
protected final Outer outer() { return Outer.this; }
}
static class InnerChild extends Inner {
InnerChild(Outer outer) {
outer.super(); // wow!
}
}
}
This is very similar to the previous workaround, except Inner is a instance class. InnerChild avoids the duplicate this$0 field because it's static. Inner provides a getter so that InnerChild can access the ref to Outer (if it wants to). This getter is final and non-virtual, so is trivial for the VM to inline.
A third workaround possibility is to store the outer class ref only in InnerChild, and let Inner access it through a virtual method:
class Outer {
static abstract class Inner {
protected abstract Outer outer();
}
class InnerChild extends Inner {
#Override protected Outer outer() { return Outer.this; }
}
}
This is probably less useful(?). One advantage is it lets InnerChild have a simpler constructor invocation, since the ref to its enclosing class will usually be passed to it implicitly. It might also be an obscure optimization if InnerChild has a different enclosing class (OuterChild, extending Outer), which it needs to access members of more often than Inner needs to access members of Outer -- it lets InnerChild use members of OuterChild without casting, but requires Inner to invoke a virtual method to access members of Outer.
In practice, all these workarounds are a bit of a nuisance, so they're only worth it if you have many thousands of instances of classes like this (which I do!).
Update!
Just realized the "qualified superclass constructor invocation" is a big piece of the puzzle as to why Javac generates duplicate fields in the first place. It is possible for an instance of InnerChild, extending Inner, both member classes of Outer, to have a different enclosing instance to what its superclass considers to be the enclosing instance:
class Outer {
class Inner {
Inner() {
System.out.println("Inner's Outer: " + Outer.this);
}
}
class InnerChild extends Inner {
InnerChild() {
(new Outer()).super();
System.out.println("InnerChild's Outer: " + Outer.this);
}
}
}
class Main {
public static void main(String[] args) {
new Outer().new InnerChild();
}
}
Output:
Inner's Outer: Outer#1820dda
InnerChild's Outer: Outer#15b7986
I still think that with some effort, Javac could eliminate the duplicate field in the common case, but I'm not sure. It's certainly a more complex problem than I first thought.