I have started learning Java language for Android Application developement.
As per my understanding based on static class, we cannot instantiate object of static class.
But why instantiation of static nested class object is allowed in following situaltion?
class EnclosingClass
{
//...
class static StaticInnerClass
{
//...
}
}
Why we can create object of inner class if it is marked as static?
EnclosingClass.StaticInnerClass s = new EnclosingClass.StaticInnerClass()
As per my understanding based on static class, we cannot instantiate object of static class.
Your understanding of the meaning of "static class" is incorrect. Basically a "static class" in Java is a nested class which doesn't have an implicit reference to an instance of the containing class. See section 8.5.1 of the JLS for more information, in particular:
The static keyword may modify the declaration of a member type C within the body of a non-inner class or interface T. Its effect is to declare that C is not an inner class. Just as a static method of T has no current instance of T in its body, C also has no current instance of T, nor does it have any lexically enclosing instances.
Perhaps you were thinking of static classes in C#, which are completely different?
Why we can create object of inner class if it is marked as static?
You may need to use a nested class in a static context, for example:
public class Test {
public static void main(String args[]) {
InnerClass innerClass = new InnerClass();
}
class InnerClass {
}
}
In this case, when you try to instantiate the innerClass you get the error:
No enclosing instance of type Test is accessible. Must qualify the
allocation with an enclosing instance of type Test (e.g. x.new A()
where x is an instance of Test).
To avoid this, you could instantiate an object of type Test and create an instance of innerClass from it:
Test test = new Test();
InnerClass innerClass = test.new InnerClass();
or better, declare also the innerClass as static and instantiate it in a static context:
public class Test {
public static void main(String args[]) {
InnerClass innerClass = new InnerClass();
}
static class InnerClass {
}
}
check it, maybe it can help you
Nested Classes
Related
I would love to understand why the following instantiation will not compile:
Superclass.Subclass myObject = new Superclass.Subclass();
The error message reads:
No enclosing instance of type Superclass is accessible. Must qualify the allocation with an enclosing instance of type Superclass (e.g. x.new A() where x is an instance of Superclass).
What is meant by enclosing instance? Why is this necessary?
It seems this message is stating that the syntax must be:
Superclass mySuperObj = new Superclass();
Superclass.Subclass mySubObj = mySuperObj.new Subclass();
BUT it fails to explain what is wrong with my method or why this alternative syntax must be used.
The new [enclosing class].[enclosed class](...) idiom is used to initialize static nested classes, that is nested classes that are declared as a static member of their enclosing class.
The [enclosing class instance].new [enclosed class](...) idiom is used to initialize inner classes, that is, nested classes that are declared as an instance member of their enclosing class.
Examples
With...
class A {
static class B {}
class C {}
}
You will use:
new A.B()
new A().new C(), or with a given instance of A called a,
a.new C()
Note
See documentation
in this case you dont talk from sub class but inner class instead....
so, in this case to create an instance of an inner class you need an instance of the outer class, so you can do:
public class Foo {
public static void main(String[] args) {
Foo myFooObject = new Foo();
Foo.InnerClass myFooInnerClass = myFooObject.new InnerClass();
System.out.println(myFooObject);
System.out.println(myFooInnerClass);
}
class InnerClass {
#Override
public String toString() {
return "Am inner class";
}
}
}
The syntax to create an Inner class object is
InnerClass innerObj = new OuterClass().new InnerClass();
NOT the
Superclass.Subclass myObject = new Superclass.Subclass();
Because :
An instance of InnerClass can exist only within an instance of OuterClass.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
InnerClass innerObj = new OuterClass().new InnerClass();
Read Java Docs for more details
I know how to make an instance of an inner class. But I want to know why we can not do that in the following way:
class outerclass{
public static void main(String[] args){
innerclass in=new innerclass();
}
class innerclass{
}
}
If I do this then I get the following error:
No enclosing instance of type outerclass is accessible. Must qualify the allocation with an enclosing instance of type outerclass (e.g. x.new A() where x is an instance of outerclass).
Why?
class Demo{
public static void main(String[] args){
System.out.println(innerclass.a);
}
static class innerclass{
static int a=1;
}
}
Gives the output 1.
See here while making the inner class as static You can easily access in your outer class,In order to create an instance of the Nested class you must reference it by prefixing it with the Outer class name, like this:
Outer.Nested instance = new Outer.Nested();
Non-static Nested Classes (Inner Classes)
Non-static nested classes in Java are also called inner classes. Inner classes are associated with an instance of the enclosing class. Thus, you must first create an instance of the enclosing class to create an instance of an inner class. Here is an example inner class definition:
public class Outer {
public class Inner {
}
}
Here is how you create an instance of the Inner class:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
Notice how you put new after the reference to the outer class in order to create an instance of the inner class.
Non-static nested classes (inner classes) have access to the fields of the enclosing class, even if they are declared private. Here is an example of that:
public class Outer {
private String text = "I am private!";
public class Inner {
public void printText() {
System.out.println(text);
}
}
}
Your innerclass is not static. This means it must have a reference to the outerclass. main is static and has no implicit outerclass.
The simple solution is to make your inner class a static nested class.
You must either make your inner class static (as already mentioned) or create your inner class from a non-static context, e.g. from a non-static method.
I.e. either this:
class outerclass{
void myMethod() {
innerclass in = new innerclass();
}
class innerclass{
}
}
or this
class outerclass{
public static void main(String[] args){
innerclass in=new innerclass();
}
static class innerclass{
}
}
outerclass thats encapsulates innerclass is not instantiated, hence, calling innerclass directly would throw an error since there is no outerclass to attach innerclass.
Therefore as suggested by the previous answers, making innerclass static would resolve the problem, allowing access to the innerclass without instantiation.
There are lot of existing answers with regards to this topic. A quick google brings this up.
Java - No enclosing instance of type Foo is accessible
On changing non-static inner class to static why there are compile time error on running code says-
Illegal enclosing instance specification
public class TestingInnerStatic{
public static void main(String args[]) {
InnerSame innerSame = new TestingInnerStatic().new InnerSame();//compile fail
Outer.InnerDiff innerDiff = new Outer().new InnerDiff();//compile fail
}
public void main() {
InnerSame innerSame = new InnerSame();
Outer.InnerDiff innerDiff = new Outer().new InnerDiff();//compile fail
}
static class InnerSame{}
}
class Outer{
static class InnerDiff{}
}
take a example of other member,this is only a convention and a good practice to call a static member on reference of class but if U call them on object they works not show compile fail.So why there is a compile fail?
If an inner class is non-static then you require an instance of the outer class to make an instance of the inner class. But that is not the case for static classes, an instance of an inner static class can exist without an instance of the outer class.
static example:
InnerClass ic = new Outer.InnerClass();
Notice I am not making a new instance of the outer class.
EDIT: reference
This is my main class:
import java.util.ArrayList;
public class MainClass {
public static void main(String[] args){
ArrayList<SecondClass.InnerClass> list=new ArrayList<SecondClass.InnerClass>();
list.add(new SecondClass.InnerClass()); //error here (read below)
}
}
Here is the second class:
public class SecondClass {
public class InnerClass{
}
}
At MainClass, at list.add, I get this error:
No enclosing instance of type SecondClass is accessible. Must qualify
the allocation with an enclosing instance of type SecondClass (e.g.
x.new A() where x is an
instance of SecondClass).
I need to have InnerClass non-static because InnerClass needs to make a static reference to a non-static method. How can I add elements in the ArrayList?
I think you need:
new SecondClass().new InnerClass()
I'd do some reading up on nested classes, and in particular the differences between static and non-static nested classes.
If you choose to make InnerClass a static nested class, note the following:
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
This means you don't need an instance of SecondClass in order to make an instance of InnerClass - You can instantiate it as you do at the moment.
If however you make InnerClass a non-static nested class (I believe these are sometimes referred to as inner classes, but double check this terminology), you need to create an instance of SecondClass in order to create an instance of InnerClass:
new SecondClass().new InnerClass()
When you want to use an innerClass you must create an instance of the class it contain innerclass. After that you'll use it. Example how to use an innerclass following the tutorial of Oracle:
SecondClass sc=new SecondClass();
SecondClass.InnerClass in=sc.new InnerClass();
And you can see detail here: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Make InnerClass static
public class SecondClass {
public static class InnerClass{
}
}
Consider the following code
class A {
static class B{
int a = 0;
}
public static void main(String argc[]) {
B var1 = new B();
B var2 = new B();
var1.a = 5;
var2.a = 6;
System.out.println(var1.a+" and "+var2.a);
}
}
It outputs 5 and 6.
Static members are loaded only once.But the output contradicts with that statement.So surely the concept of static classes is different from static data members.So what does static mean in case of static classes
A copy paste from oracle:
Static Nested Classes
As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference.
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
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();
An example:
There is no need for LinkedList.Entry or Map.Entry to be top-level class as it is only used by LinkedList aka Map. And since they do not need access to the outer class members, it makes sense for it to be static - it's a much cleaner approach.
Static, in case of classes, means that they are not related to an instance of their outer class:
class A{
class B{
...
}
}
...
new A.B(); //error
is invalid. Because B is not static, it holds an implicit reference to an instance of A. This means you cannot create an instance of B without an instance of A.
class A{
static class B{
...
}
}
...
new A.B();
is perfectly valid. Since B is static, it doesn't hold a reference to A, and can be created without an instance of A existing.
Static class is a class that doesn't hold an implicit reference to its enclosing class. Static class behaves just like an ordinary class except its namespace being within another class.
Non-static inner class holds an implicit reference to its enclosing class. The enclosing class' variables are directly accessible to an instance of the inner class. A single instance of the outer class can have multiple instances of its inner class(es).
You've misunderstood the concept. B is a static class with an int a attribute. In your code, you're creating two instances of the B class and each instance has its own a attribute with its value 5 and 6 respectively. Don't confuse the static class with the static attribute/method of a class.
The behavior you're trying to get can be done if you add the static modifier to the a attribute on the B class. Otherwise, your code it's like this:
class B{
int a = 0;
}
class A {
public static void main(String argc[]) {
B var1 = new B();
B var2 = new B();
var1.a = 5;
var2.a = 6;
System.out.println(var1.a+" and "+var2.a);
}
}