Anonymous innerclass declared in an interface: what is the outerclass? - java

Consider the following:
public class OuterClass {
private String attribute = "outer";
class InnerClass {
private String attribute = "inner";
public doSomething() {
System.out.println(this.attribute);
System.out.println(OuterClass.this.attribute);
}
}
}
The InnerClass is not static and must be created against an instance of it's outer class.
new OuterClass().new InnerClass()
The regular innerclass holds a reference to the outer class in which it was created, that is accessible using Outer.this.myAttribute (particularly useful in this case where there is a "naming colision"
When creating an anonymous innerclass, it's the same: the anonymous innerclass created holds a reference to the outer class, this is why when declaring a predicate inside a method (anonymous method-local innerclass), we can still access, inside the innerclass, the variables of the outerclass without having to declare them final (while we should for variables passed as method parameters.
public class OuterClass {
// Do not need to be final because the innerclass keeps a reference to the outerclass
// even if it's an anonymous innerclass, it's still an innerclass
private String classAttribute = "classAttribute";
public Runnable doSomething() {
// Should be final because the variable lives on the stack and the reference to this object
// must be copied so that the String object is still accessible when the stack frame is destroyed
final String localVar = "localVar";
return new Runnable() {
#Override
public void run() {
System.out.println(classAttribute);
System.out.println(localVar);
}
};
}
}
And finally, we can declare constants in an interface, which are implicitly marked public static final. An object can be a constant.
Thus an object created as an anonymous innerclass is a legal constant for an interface.
For exemple, when using Guava, I usually declare in my interface functions and predicates which permits me to leverage the useful Guava functions like Maps.uniqueIndex(...).
public interface AlternativeNameable {
String getAlternativeName();
Function<AlternativeNameable,String> GET_ALTERNATIVE_NAME = new Function<AlternativeNameable,String>() {
#Override
public String apply(AlternativeNameable input) {
return input.getAlternativeName();
}
};
}
So you may ask yourself what is my question? Here it is:
When declaring an anonymous class as an interface constant (see my last code sample), on which outerclass does the anonymous innerclass holds a reference to?

Fields defined in interfaces always implicitly have the modifiers public static final. It's a constant, and as such it has no associated outer class.
Also, member types of interfaces are implicitly public and static, which holds true for anonymous classes as well.

Inner classes of interfaces are implicitly static and as such, do not require reference to outer class.

Related

What is the Java syntax of using dot new after an object? [duplicate]

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);
}*/
//}
}
}

Accessing outer-class fields through inner-class instance from outer-class

This is a short subquestion of a larger question I am working towards to.
Why can't I access the outer classes field through an instance of inner class in outer class in line 8?
The field is visible from inner class.
The problem persists for non-static methods in outer class.
The visibility of the field does not matter. Its visible from inner class either way.
The field could be accessed through a (private) getter in inner class, but one of the reasons for my problem is, that i would like to avoid those.
It's supposed to become a variation of the immutable builder pattern, so outer and inner class are developed in close coherence. That's the only reason I would dare to access the fields directly w/o getters.
public class OuterClass {
private static OuterClass instanceOf(InnerClass innerClass) {
return new OuterClass(innerClass.outerField);
}
public static OuterClass instanceOf(int arg) {
return new OuterClass(arg);
}
private int outerField;
private OuterClass(int arg) {
this.outerField = arg;
}
// Outer class getters...
public InnerClass build() {
return new InnerClass(this);
}
public class InnerClass {
private InnerClass(OuterClass outerClass) {
outerField = outerClass.outerField;
}
// Inner class setters......
public OuterClass build() {
return OuterClass.instanceOf(this);
}
} // End InnerClass
} // End OuterClass
Why can't I access the outer classes field through an instance of
inner class in outer class in line 8?
Because the field is a field of the class OuterClass and not of the class InnerClass. So to access it, you need an instance of the class OuterClass, not of the class InnerClass.
Sure, inside InnerClass definition, you can implicitly access all the fields of OuterClass. But that's only a matter of access from inside this context. You're not specifying what is the object of which you're trying to access the field, so the language automatically selects that for you. It's usually this.field, but in the case of a field from the containing class, it's actually OuterClass.this.field.
Once you're trying to indicate what is the object of which you're trying to access a field, rather than let the language implicitly select that object for you, well this object must actually be of the class that contains the field.

Access methods within local inner classes in Java

Is there any way to access the methods of local inner classes in Java. Following code is the sample code that I tried before. According to that what is the mechanism to access the mInner() method?
class Outer{
int a=100;
Object mOuter(){
class Inner{
void mInner(){
int y=200;
System.out.println("mInner..");
System.out.println("y : "+y);
}
}
Inner iob=new Inner();
return iob;
}
}
class Demo{
public static void main(String args[]){
Outer t=new Outer();
Object ob=t.mOuter();
ob.mInner(); // ?need a solution..
}
}
As ILikeTau's comment says, you can't access a class that you define in a method. You could define it outside the method, but another possibility is to define an interface (or abstract class). Then the code would still be inside your method, and could access final variables and parameters defined in the method (which you couldn't do if you moved the whole class outside). Something like:
class Outer {
int a = 100;
public interface AnInterface {
void mInner(); // automatically "public"
}
AnInterface mOuter() { // note that the return type is no longer Object
class Inner implements AnInterface {
#Override
public void mInner() { // must be public
int y = 200;
System.out.println("mInner..");
System.out.println("y : " + y);
}
}
Inner iob = new Inner();
return iob;
}
}
class Demo {
public static void main(String[] args) { // the preferred syntax
Outer t = new Outer();
Outer.AnInterface ob = t.mOuter();
ob.mInner();
}
}
Note: not tested
Note that the return type, and the type of ob, have been changed from Object. That's because in Java, if you declare something to be an Object, you can only access the methods defined for Object. The compiler has to know, at compile time (not at run time) that your object ob has an mInner method, and it can't tell that if the only thing it knows is that it's an Object. By changing it to AnInterface, the compiler now knows that it has an mInner() method.
The scoping rules of a local class are pretty much the same as the scoping rules of a variable, that is, it is confined to the enclosing block.
The same way you cannot access variable iob from main, you cannot access local class Inner from main.
Outside the enclosing block, there's no difference between a local class and an anonymous class. Neither can be accessed. The difference is that within the enclosing block, the local class can be accessed by name, especially useful if you need to access it repeatedly, e.g. to create multiple instances.
The only way to interact with a local/anonymous class outside the enclosing block, is through any superclass or interface implemented by the class in question.
To access the inner class create an object of inner class..
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
from your example
outer t=new outer();
outer.inner inner1=t.new inner();
Hope this helps you...

Effective java Item no 74(on serialization): Implement Serializable judiciously

It item no 74 of effective java book there is a paragraph (2nd para from last of the item 74) which mentions as per below:
Inner classes (Item 22) should not implement Serializable. They use
compiler-generated synthetic fields to store references to enclosing
instances and to store values of local variables from enclosing
scopes. How these fields correspond to the class definition is
unspecified, as are the names of anonymous and local classes.
Therefore, the default serialized form of an inner class is ill-
defined.
I know about inner class uses compiler generated synthetic field to store reference to enclosing instances e.g. if the enclosing class is MyEnclosing and inner class is MyInner then the enclosing reference is MyEnclosing.this. But i am not able to get the BOLD part. Please help me getting the meaning. Thanks!!!
Suppose you have a local class like this:
class OuterClass {
Runnable run;
void method() {
final int a = 8;
this.run = new Runnable() {
public void run() {
System.out.println(a);
}
};
}
}
Now suppose I try to serialize this, which contains an object of this inner class type. My compiler names that class OuterClass$1 and gives it a field called val$a. But the exact names to be used in this situation are not part of the compiler's spec. Another compiler might choose to call the inner class OuterClass$method$1. In that case, serializing in one compiled version and deserializing in the other would fail, even though the same source file was used.
(Plus, there's also the problem that an anonymous inner class does not have a no-args constructor. But due to the problem above, even a named inner class cannot reliably serialize)
Consider the following code:
public class Main {
public static void main(String[] args) {
final int x = Integer.valueOf(args[0]);
new Object() {
void print() {
System.out.println(x);
}
}.print();
}
}
My compiler calls the anonymous inner class Main$1. When I disassemble it, I see that a copy of the value of x from the outer scope is stored in a private field called val$x:
private final int val$x;
This is an example of what the bold part is talking about.
An inner class is a non-static class defined within some other class:
class Outer implements Serializable {
private String someString;
class Inner implements Serializable {
private int someInt;
}
}
Once you have an instance of the Inner class, when you serialize it, it must have a reference to the outer class (which it accesses internally via the Outer.this reference) and how this is achieved for a serialized object is unspecified. The same applies to a local class:
class Outer implements Serializable {
private String someString;
Serializable method(final int i) {
class Inner implements Serializable {
Inner() {
System.out.println(i);
}
}
return new Inner();
}
}
If you serialize the value returned by method(), it would need to have a reference to i, but that's not reliable.

Why a non-static inner-class cannot have static members (fields and methods)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why cant we have static method in an inner class?
I know that the creation of a non-static inner-class object requires an outer-class object and the created non-static inner-class object automatically have a hidden reference to the object of the outer-class. But why can't a non-static inner-class have static members? The Java designer just have to disallow the access of non-static outer-class fields inside a static method of the inner-class, it would make more sense, non?
If it does not make sense to have static members in an inner class, why inner class can inherit static members by inheriting a class who has static members?
I read this post too. As is mentioned:
Inner classes may inherit static members that are not compile-time
constants even though they may not declare them. Nested classes that
are not inner classes may declare static members freely, in accordance
with the usual rules of the Java programming language.
Is it a convention?
Here is my code:
public class OuterClass {
private int outerClassField;
public void doSomethingOuterClass() {
outerClassField = 1;
}
public static void doSomethingStaticOuterClass() {
// outerClassField = 2; // Error: Because static method cannot access an specific object's field
}
public class InnerClass extends ClassWithStaticField {
// Error: Why a non-static inner class cannot have static fields ?
// public static int innerClassStaticField = 1;
public void doSomethingInnerClass() {
outerClassField = 3;
staticField = 1;
}
// Error: Why a non-static inner class cannot have static methods ?
// public static void doSomethingStaticInnerClass() {
// outerClassField = 4;
// }
}
public static void main(final String[] args) {
// If it does not make sense to have static members in an inner class, why inner class can inherit statis members by inheriting a class who has static
// members?
OuterClass.InnerClass.staticField = 1;
OuterClass.InnerClass.staticMethod();
}
}
class ClassWithStaticField {
public static int staticField;
public static void staticMethod() {
};
}
1. An object of a Non-static inner class is associated with an instance/object of its Outer Class (ie enclosing class).
2. The entire body of a Non-static inner class is Not within a static scope, and therefore you can't have static members in there.
3. Instance variables and methods in the non-static inner class are relative to an instance of the enclosing class, so being related to an object, static won't hold true for them (ie inner class),
4. When we create an Instance of non-static inner class, we Need an Object of Outer enclosing class. The innernon-static class has an implicit reference to it outer enclosing class.
Eg:
Outer o = new Outer();
Outer.Inner i = o.new Inner();
Technically there I don't know of any reason why the language restricts the use of static elements for inner classes.
A nonstatic inner class can be emulated by using a normal class that takes the (formerly) enclosing instance as an argument to the constructor. Of course there are many little differences when it comes to visibility rules an visibility scopes.
I presume it was a language design decision, mostly because statics in non-static inner classes are confusing and non-intuitive to access (Outer.Inner.StaticMember).
There is no point of providing a static method inside a non static inner class.
You could use a non static method inside the outer class instead ?

Categories

Resources