Static Nested class can be extended by not non-static [duplicate] - java

This question already has answers here:
no enclosing instance of type... in scope
(2 answers)
Closed 5 years ago.
My code is as following :-
A class T can extend ClassO.Four. Four is a static class inside ClassO but cannot extend ClassO.Two Two is an inner class inside ClassO. I am getting error
No enclosing instance of type ClassO is available due to some intermediate constructor invocation
What is the reason of difference in behaviour?
class ClassO
{
interface inner
{
void msg();
}
class Two implements inner
{
public void msg()
{
System.out.println("Class Two");
}
}
static class Four
{
public void msg()
{
System.out.println("Class Four");
}
}
public void m()
{
}
}
class T extends ClassO.Two **// can extend ClassO.Four but not ClassO.Three**
{
public void msg()
{
System.out.println("Class Two");
}
}

Recall that a static inner class is a "normal" class with the name nested inside its owner class, and additional access privileges to private static members of its owner class. As a result, static inner classes have no restrictions as to the location from which they could be instantiated.
In contrast, a non-static inner class has access to both static and non-static members of its owner class. To make this possible, Java compiler embeds a hidden pointer to the owner into the nested class, and passes an instance of the owner to that constructor.
This behavior relies on the availability of owner's this at the point of instantiation of the non-static inner class. If compiler were to allow you to inherit from a non-static member outside its owner, it wouldn't be able to instantiate your derived class, in effect forcing it to behave as if it were an inner class. That is why the compiler prohibits such inheritance.

Related

difference between extends inner class and extends nested class? [duplicate]

This question already has answers here:
Java: Non-static nested classes and instance.super()
(5 answers)
Closed 6 years ago.
class OuterClass
{
static class InnerClassOne
{
//Class as a static member
}
class InnerClassTwo
{
//Class as a non-static member
}
}
class AnotherClassOne extends OuterClass.InnerClassOne
{
}
class AnotherClassTwo extends OuterClass.InnerClassTwo
{
public AnotherClassTwo()
{
new OuterClass().super(); //accessing super class constructor through OuterClass instance
}
}
i have theses classes, why when extends from nested class we do not call outer class constructor , but when extends from inner class should call outer constructor through outer object, so what is the difference and why??
The reason is simple. To access a static property you don't need to create an object i.e. you don't need to instantiate the class.
But if you want to access a non static property you will first need to create an object of that class and then use it.
So here in your case when you want to extend InnerClassTwo(which is an inner class and non static) you will have to associate it with the constructor of the outer class AnotherClassTwo, as it can be thought of as a property of that outer class.

How do I access the instance of an enclosing class? [duplicate]

This question already has answers here:
Calling outer class function from inner class [duplicate]
(2 answers)
Closed 7 years ago.
My question, in abstract terms, is:
How can a non-static inner class access the instance of the enclosing class? This is required for purposes of using the instance as a parameter in method calls and accessing methods and variables with identical names between the inner and enclosing class.
Like the keywords this and super allow you to access specific versions of methods and variables with identical names in the class and the parent, are there keywords to access versions of methods and variables in enclosing classes and enclosed classes?
If you are confused, continue reading:
Consider the following code example, with two classes and an inner class. Main and Outer are two classes in the package "myPackage" (on a side note, I could not get the following code to work without a package/in the default package, for unknown reasons). Inner is an inner, non-static class of Outer.
package myPackage;
public class Outer {
public void activate() {
System.out.println("Outer.activate");
}
public class Inner {
public void go() {
activate();
}
}
}
package myPackage;
import myPackage.Outer.Inner;
public class Main {
public static void main(String[] args) {
Outer myOuter = new Outer();
Inner myInner = myOuter.new Inner();
myInner.go();
}
}
Note that I construct an Inner with myOuter.new Inner(). Since Inner is non-static, it has to be constructed on top of an existing instance of its enclosing class: in this case, myOuter. Therefore, when I call myInner.go(), myInner calls activate(), which calls activate() on its linked instance of the enclosing class. So myInner calls myOuter.activate(), and the output is:
Outer.activate
Now, consider the following changes:
package myPackage;
public class Outer {
public void activate() {
System.out.println("Outer.activate");
}
public class Inner {
public void activate() {
System.out.println("Inner.activate");
activate();
}
}
}
package myPackage;
import myPackage.Outer.Inner;
public class Main {
public static void main(String[] args) {
Outer myOuter = new Outer();
Inner myInner = myOuter.new Inner();
myInner.activate();
}
}
Now when I call myInner.activate(), myInner outputs, then calls activate(). However, since Inner now has a method called activate(), myInner uses that version instead of the version in the instance of the enclosing class. So myInner calls myInner.activate(), and the output is:
Inner.activate
Inner.activate
Inner.activate
Inner.activate
Inner.activate
Inner.activate
...
Over and over, and ends in a stack overflow error. So my question in this context is how to change Inner.activate() such that it outputs, then calls its enclosing instance version's of activate() instead of its own. The output would then be:
Inner.activate
Outer.activate
Thanks in advance for your assistance.
You access this of the outer class by pre-pending the name of the class to this keyword, as follows:
Outer.this.activate();
This resolves the scope of this to reference the object of the outer class, which is implicitly stored inside objects of non-static inner classes.
Demo.

Java: reference outer class in nested static class [duplicate]

This question already has answers here:
Java inner class and static nested class
(28 answers)
Closed 7 years ago.
I have a class structure like this:
public class OuterClass {
private static class InnerClass {
public void someMethod() {
OtherClass.otherMethod(<???>);
}
}
which refers to a static method of some other class OtherClass:
public class OtherClass {
public static void otherMethod(OuterClass) {
....
}
}
I am trying to figure out what to put in place of the <???>. How do I refer to the instance of the outer class from within the inner static class? What I would like to do is to refer to the implicit this of the OuterClass.
You obviously need an object of OuterClass type:
public void someMethod() {
OuterClass oc = new OuterClass();
OtherClass.otherMethod(oc);
}
In case that your inner class is not static, then you could do:
//remove static here
private class InnerClass {
public void someMethod() {
OtherClass.otherMethod(OuterClass.this);
}
}
You should know the different between nested classes - static and non static. Static nested classes are simply classes like every other, just defined within other class (usually because of encapsulation principle). Inner static class instances have no knowledge of outer class instance.
Nested inner classes (non static) mandate that an object of the inner class exist within an instance of the outer class. That's why you can access it via OuterClass.this.
The simpliest way is to pass an instance of the outerClass in the constructor or in the method since the innerClass don't know this class.
like this:
public void someMethod(OuterClass outerClass) {
OtherClass.otherMethod(outerClass.myMethod());
}

Instantiate an Inner class from within a static method of its enclosing Class [duplicate]

This question already has answers here:
How to instantiate non static inner class within a static method?
(4 answers)
Closed 9 years ago.
we know that Static contexts can't reference any instance of any type, but what happens with main method, how the following code sample compiles with no problem:
public class MyOuter
{
public static void main(String[] args)
{
MyOuter mo = new MyOuter(); // gotta get an instance!
MyOuter.MyInner inner = mo.new MyInner();
inner.seeOuter();
//Or
MyOuter.MyInner inner = new MyOuter().new MyInner();
}
class MyInner
{
public void seeOuter(){}
}
}
isn't it forbidden to instantiate an inner class from within a static context in it's enclosing class?
isn't it forbidden to instantiate an inner class from within a static context in it's enclosing class?
No - it's forbidden to instantiate an inner class without an instance of the enclosing class. In your case, you do have an instance of the enclosing class:
new MyOuter().new MyInner();
That's entirely fine.
The only reason you can normally get away without specifying the enclosing class from an instance method is that it's equivalent to
// Within an instance method
this.new MyInner();
See section 15.9.2 of the JLS for more details. Your constructor call is a "qualified class instance creation expression".

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