Java object instantiation from nested class - What's wrong with this: - java

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

Related

A query about class nesting in java

public class Outer{
public class Inner{
}
}
public class Main {
public static void main(String[] args) {
Outer objOut = new Outer();
//Outer.Inner object1= objOut.new Inner(); // runes without a problem
//objOut.Inner object2= objOut.new Inner(); //gives error
}
}
This might sound little amateur but, What are the difference between Outer.Inner vs objOut.Inner.
You cannot use a variable name as the type of another variable, which is what you're trying to do with objOut.Inner. The type of the variable is Inner (or optionally Outer.Inner).
Because Inner is an inner class, it's associated with an instance of its outer class (its enclosing instance). When you create an instance of it, you can optionally¹ specify what object instance it's associated with, which is what you're doing with objOut.new Inner.
This example may help make it a bit clearer:
public class Example {
private String str;
public class Inner {
void show() {
// Show the string for the Example this Inner is part of
System.out.println(Example.this.str);
}
}
public Example(String s) {
this.str = s;
}
public static void main(String[] args) {
Example e1 = new Example("e1");
Example e2 = new Example("e2");
Inner i1 = e1.new Inner();
i1.show(); // "e1"
Inner i2 = e2.new Inner();
i2.show(); // "e2"
}
}
Live Copy
Notice how the i1 Inner instance gets e1 as its enclosing Example instance, and so sees e1's str, but i2 gets e2 as its enclosing instance so it sees e2's str.
I suggest this Java tutorial for more information.
¹ Sometimes it's not optional, such as in my Example class above, since where new Inner is used, there's no default instance it could use. It would be optional in an instance method of Example, but not in that static method.
This one :
Outer.Inner = objOut.new Inner();
will not compile but if you change it to :
Outer.Inner object = objOut.new Inner();
will mean creating an instance of inner class which has reference to Outer class - objOut will be instance of Outer class.
Also this :
objOut.Inner = objOut.new Inner();
will not compile since objOut which is the instance of Outer class does not have poperty Inner.
And it is not Outer class that knows the instance of Inner class - it is Inner class instance that knows the Outer class instance with which it was created.
EDIT
The line :
objOut.Inner object2= objOut.new Inner();
will not compile since Inner type identifer belongs to Outer class and not instance of this class.
Both don't compile.
To make the former compile, a variable should be declared, and the name to that variable should be given.
Outer.Inner obj = objOut.new Inner();
The latter wouldn't compile even if you did this step since objOut.Inner is neither a type (because the primary expression objOut is not a type) nor a valid name (because . is not allowed within an identifier (jls-3.8)).
A simplified rule (jls-14.4) for your case would be
LocalVariableType VariableDeclaratorId [= VariableInitializer];

Why we can not make an instance of inner class inside the main method of outer class in regular way?

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

Understanding inner class in Java

Consider the following class:
package test;
public class Container {
public class Contained {
public void foo() {
System.out.println("printed");
}
}
}
and the Main.java:
package test;
public class Main {
public static void main(String[] args){
Container c = new Container();
}
}
So, we right here have created the instance of the Container class. Does it mean that we've also created the instance of the inner class? I thought, yes it does, because the inner class is a non-static nested class. But how can we get access to the instance of the inner class? Can we ever create the instance outside of the Container class?
It would be very useful if you provided some references to the JLS.
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 = outerObject.new InnerClass();
So in your case it will be
Container container = new Container();
Container.Contained containedClass = container.new Contained();
This is called Inner Class. In inner class you can access the container class members
To create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
This is called Static Nested Class. In Static Nested Class you can not access the container class instance members but only static members
Creating an instance of Container doesn't create an instance of the Contained class, since there can many many instances of Contained associated with the same instance of Container. You create instances of Contained explicitly.
Yes, you can create an instance outside Container class by specifying the instance of Container that would be associated with it :
Container cr = new Container();
Container.Contained cd = cr.new Contained ();
Inner classes are described in JLS 8.1.3.

Concept Behind Static classes in Java

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

Why instantiation of static nested class object is allowed?

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

Categories

Resources