public class ABC extends XYZ
{
public static class InnerClass1
{
...
}
public static class InnerClass2
{
...
}
public static class InnerClass3
{
...
}
public static class InnerClass4
{
...
}
}
In the above code, I cannot access the methods of the class XYZ inside the inner classes1,2,3 and 4. How can i modify the above structure so that the inner classes can access the methods within the class XYZ ?
Thanks in advance !
public class ABC extends XYZ
{
public static class InnerClass1
{
...
}
InnerClass1 is not an inner class. It's a nested class, because of the word static.
If there were no static, it would be an inner class. And any instance of that inner class would have a hidden reference to an ABC (which is also an XYZ). If the inner class called any instance methods of ABC or XYZ, or referred to any instance variables in those classes, it would use that hidden reference to call the instance methods or access the instance variables.
Since it's a nested class, though, there is no hidden reference to an ABC (or XYZ). Thus, if you call an instance method or refer to an instance variable, it can't do it, because there is no ABC object to work with. (However, you can still call a static method of an ABC, or refer to a static variable.)
I'm not sure what the solution is--it depends on your needs. It's possible that the XYZ methods you can't call don't actually need an XYZ object to work on, and therefore those methods should be static. It's also possible that the nested class should have some explicit ABC or XYZ variable that it uses to access the instance methods; you can still call instance methods from a nested class if you have an object to work on:
public static class NestedClass {
XYZ x;
void someMethod() {
x.instanceMethod(); // legal even if instanceMethod is non-static
}
}
The other solution would be to remove the word static, so that InnerClass1 really has a hidden reference to an ABC. This means that when you create an InnerClass1 instance, you need some ABC object for it to refer to. If you create this in some other class, the syntax would be something like
ABC abcObject;
...
ABC.InnerClass1 newObject = abcObject.new InnerClass1();
static inner class can only access static members of the outer class
so the inner class will only be able to use the static members of xyz.
create the inner class non static if you want to access everything
You have two options, one remove the static call so a hidden this reference to the outer class is available to the inner class instances or two, when you create an instance of the inner class pass in a this explicitly, example:
public class ABC extends XYZ
{
XYZ.InnerClass innerInst = new InnerClass(this);
public static class InnerClass1
{
private final ABC extref;
public void Innerclass(ABC outerref)
{
extref = outerref;
}
...
}
}
Related
I cannot figure out if this is a hidden feature I have never discovered or a bug from IntelliJ Idea.
Having this class,
public class StackOverflow {
private String abc;
public static class StackOverflowExtended extends StackOverflow {
public StackOverflowExtended() {
abc = "";
}
}
}
IntelliJ tells me that I cannot access abc because either it has private access or because I'm in a static context.
As soon as I access abc by super, it starts working.
public class StackOverflow {
private String abc;
public static class StackOverflowExtended extends StackOverflow {
public StackOverflowExtended() {
super.abc = "";
}
}
}
There's no bugs or hidden features going on. You're probably mixing up inheritance and inner classes.
A non-static inner class can access the variables of its outer class, even if they're private.
public class StackOverflow {
private String abc;
public class StackOverflowExtended extends StackOverflow {
public StackOverflowExtended() {
abc = "";
}
}
}
A static inner class cannot access the fields of its outer class, because it's static. It can exist without having an instance of its outer class.
The reason why super.abc works on the static inner class, is due to it being its subclass. Accessibility independent of its scope, is then again due to it being an inner class.
The scope and accessibility of any private member (field, constructor or method) is the complete body of its declaring class, including any nested classes.
If the inner class is non-static, it is bound to the instance of the outer class, so you can access the private instance variable.
In your case, the inner class is static, so you need to specify an object instance of the outer class, such as super (because in your case the inner class extends the outer class).
The only "weird" thing is that when you try to access it using this.abc, it fails because then apparently the rule that subclasses cannot access private members of their parents takes precedence.
public class InnerTest {
public static void main(String arg[]) {
A.B.print();
}
}
class A {
static class B {
static void print() {
System.out.println("Hello");
}
}
}
How can i call static class B using class name A although class A is not static
This is not related to the class to be static or not, it is related the static keyword in the method.
take a look about How static keyword exactly works in Java? also read this article Java – Static Class, Block, Methods and Variables
One more aspect how to explain this:
class itself is not static or non static it is just a class.
You anyway can use static keyword only with class members. If you would try to declare InnerTest as static you would have an error that might look like this (so assuming it is not static nested class to some other class)
Illegal modifier for the class InnerTest; only public, abstract &
final are permitted
static nested class can be used as in question because it does not require access to any instance member of InnerTest. In other words it can access static members and only those.
If it needs access to non static members then it can not be static and the way to call would be like new InnerTest().new B().
The static keyword is used to modify a member of a class. When a member is modified with static, it can be accessed directly using the enclosing class' name, instead of using an instance of the enclosing class like you would with a non-static member.
The inner class Inner below is a member of the class Outer:
class Outer {
static class Inner {}
}
Therefore, Inner can be accessed like this:
Outer.Inner
Outer don't need to/cannot be modified by static because it is not a member of a class. It is a class existing in the global scope. To access it, you just write its name - Outer. It does not make sense for it to be non-static because it has no enclosing class. If it were non-static, how are you supposed to access it?
To use the correct terminology, class B is not an inner class; it is a static nested class. See https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html for the definitions of the various types of nested class.
The important keyword is the static keyword in front of the definition of class B. It does not matter whether class A is static or not. In fact, it wouldn't make sense to put static in front of class A's definition.
Because class B is declared static, it doesn't keep a reference to an instance of class A.
//below class is the example where in subclass extends the innerclass and from the subclass i am trying to access the methods of outer class i.e encapsulating class of inner class.
package innerClass;
public class outterclass {
private int outer=24;
protected int get_outer(){
return outer;
}
protected static class innerclass{
private int outer=25;
protected int get_outer(){
return outer;
}
}
}
package innerClass;
public class subclass_B extends outterclass.innerclass {
void parent_class_info_fetch(){
System.out.println(get_outer());
//i want to access the outer class get_outer method and how do i achieve that?
}
public static void main(String[] args) {
InheritanceStaticInnerClass_B isb=new InheritanceStaticInnerClass_B();
isb.parent_class_info_fetch();
}
}
Your innerclass is not an inner class. It is a static nested class and bears no special relationship to its enclosing class. You cannot reach an instance of the enclosing class because no such instance is available to innerclass or its subclasses.
If innerclass was indeed inner, then you would have to instantiate it with an enclosing instance:
outterclass outer = new outerclass();
subclass_B b = outer.new subclass_B();
Then, in parent_class_info_fetch() you could write
outterclass.this.get_outer()
to reach that method.
Of course, there would be several layers of bad practices in such code, so consider this just an academic execrise.
You should also learn about the basic naming conventions in Java.
The class outterclass.innerclass is a static class field, which means you don't necessarily have an enclosing instance of outterclass. On the other hand, the method get_outer of outterclass is an instance method, so you'll need the enclosing instance to call it.
With the class hierarchy you have, you'd have to make get_outer static (which requires making outer static as well).
I need to reference a variable of a top level class from a method within a static class.
This method should act on unique instances of the top level class and so it feels like I shouldn't instantiate the top level class inside the static class.
Basically I want something like
public class TopLevel{
// private
int innerV
public static class Inner implements X {
for(i=0; i<innerV,i++){
doSomething
}
}
}
Is it possible to just say this.innerV or something similar in the for loop and similar places?
From a static inner class, you can't refer to (nonstatic) members of the outer class directly. If you remove the static qualifier, it will work, because instances of nonstatic inner classes are implicitly tied to an instance of the containing class, so they can refer to its members directly.
Declaring your inner class static removes this link, so you need to either pass an instance of the outer class to the inner class method (or its constructor) as a parameter, or create it inside the method.
You can't do that. Create a TopLevel instance and if you make an innerV accessor (getter/setter) or make it public, than you can.
public class TopLevel {
public int innerV
public static class Inner implements X {
for(i=0; i<innerV,i++){
TopLevel tl = new TopLevel()
tl.innerV = 12345678;
}
}
}
You can't do that because it doesn't make sense, any more than referring to a non-static member from a static function makes sense. There is no current instance of the outer class in the context of the static inner class to get the instance variable from.
I created a non-static inner class like this:
class Sample {
public void sam() {
System.out.println("hi");
}
}
I called it in main method like this:
Sample obj = new Sample();
obj.sam();
It gave a compilation error: non-static cannot be referenced from a static context When I declared the non-static inner class as static, it works. Why is that so?
For a non-static inner class, the compiler automatically adds a hidden reference to the "owner" object instance. When you try to create it from a static method (say, the main method), there is no owning instance. It is like trying to call an instance method from a static method - the compiler won't allow it, because you don't actually have an instance to call.
So the inner class must either itself be static (in which case no owning instance is required), or you only create the inner class instance from within a non-static context.
A non-static inner class has the outer class as an instance variable, which means it can only be instantiated from such an instance of the outer class:
public class Outer{
public class Inner{
}
public void doValidStuff(){
Inner inner = new Inner();
// no problem, I created it from the context of *this*
}
public static void doInvalidStuff(){
Inner inner = new Inner();
// this will fail, as there is no *this* in a static context
}
}
An inner class needs an instance of the outer class, because there is an implicit constructor generated by compiler. However you can get around it like the following:
public class A {
public static void main(String[] args) {
new A(). new B().a();
}
class B {
public void a() {
System.err.println("AAA");
}
}
}
Maybe this will help : http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
the non-static inner class cannot be called in a static context (in your example there is no instance of the outer class).