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.
Related
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.
Consider the below example
Why we are restricted to declare static member variable in inner Class when there isn't any restriction on inheriting static variables in Inner classes?
public class Outer {
public class Inner {
public static String notAllowed;
/* Above line give following compilation error
The field notAllowed cannot be declared static in a non-static inner type, unless initialized with a constant expression
*/
}
}
But now if my inner class extends other class which contains static variable than this works fine.
Consider below code:
public class Outer {
public class Inner extends InnerBase {
/* Since it extends InnerBase so we can access Outer.Inner.allowed */
public Inner(){
Outer.Inner.allowed = null; // Valid statement
}
}
}
public class InnerBase {
public static String allowed;
}
So what is the reason for restricting static variable in inner class as it is achievable through inheritance?
Am I missing something very basic?
From oracle website:
As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields.
Because an inner class is associated with an instance, it cannot define any static members itself.
I understand it this way:
If inner class have their own static field,and static field have to initialize before class instantiate;
But a innner class only exist with an instance of outterclass ,so it can not initialize its static member before instantiate,then in Contradiction.
Because in order to access the static field, you will need an instance of the Outer class, from which you will have to create an instance of the non-static Inner class.
static fields are not supposed to be bound to instances and therefore you receive a compilation error.
The JLS 8.1.3 specifies:
Inner classes may not declare static initializers or member
interfaces, or a compile-time error occurs.
Inner classes may not declare static members, unless they are constant
variables, or a compile-time error occurs.
It is very much possible that the purpose of declaring a static variable opposes the purpose of declaring ANY variable in an inner class. Static variables are meant to be used statically - in any other static methods and classes, while inner classes imply that those classes serve their outer classes ONLY.
I guess the Java creators just wanted it this way.
Just looking for a confirmation.
public class Indeed{
public static class Inner implements Runnable{
public void run()
{
System.out.println("Indeed");
}
}
public static void main (String []args)
{
Indeed.Inner inner = new Indeed.Inner();
inner.run();
}
}
As you can see in the code above, I can declare public void run() without declaring it static. I guess it's implicitly done. Isn't it?
One more question related: Why I cannot use the method run as following: Indeed.Inner.run(); it is static after all, there should not be any need of instantiating the inner member at all? ( I know I am wrong as it does not compile if I do that, however I would like to know why).
Thanks in advance.
As you can see in the code above, I can declare public void run() without declaring it static. I guess it's implicitly done. Isn't it?
No.
One more question related: Why I cannot use the method run as following: Indeed.Inner.run();
Becuase it's not static.
static class is only valid for inner classes and you can point to a static class by its enclosing class as Indeed.Inner.
This is different from non-static inner class where you need an instance of the enclosing class to create an instance of the same class. For example:
Indeed.Inner inner = new Indeed().new Inner();
No, run() is an instance method of the static class Inner. A static (inner) class just makes it possible to use an instance of the class without an enclosing parent instance. When you do Indeed.Inner inner = new Indeed.Inner();, you are creating an instance of the static class, and you are invoking it's run() method on this instance.
A static class is just a regular class, in fact more so than a non-static class.
The difference between a static nested class and a top-level class is just access scoping: the static class can access private members of its enclosing class.
Once you get that cleared up, you won't need to ask the question that you are asking here.
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Non-static nested classes (inner classes) have access to other members of the enclosing class
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class.
Static inner class
public static class Inner implements Runnable
means you can create the instance of them, without having to create the instance of outer class (Indeed)
Indeed.Inner inner = new Indeed.Inner();
Why I cannot use the method run as following: Indeed.Inner.run() ?
the run method is by default not static. To call Indeed.Inner.run() directly, you need to make run() method static too
I have an inner class in my Java class.
When I run find bugs, it recommends(warns) to make it as static.
What's the point of this warning? What's the advantage of making a inner class as static?
If the nested class does not access any of the variables of the enclosing class, it can be made static. The advantage of this is that you do not need an enclosing instance of the outer class to use the nested class.
An inner class, by default, has an implicit reference to an object of the outer class. If you instantiate an object of this from the code of the outer class, this is all done for you. If you do otherwise you need to provide the object yourself.
A static inner class does not have this.
That means it can be instantiated outside the scope of an outer class object. It also means that if you 'export' an instance of the inner class, it will not prevent the current object to be collected.
As a basic rule, if the inner class has no reason to access the outer one, you should make it static by default.
A static inner class is a semantically simpler thing. It's just like a top-level class except you have more options for visibility (e.g. you can make it private).
An important reason to avoid non-static inner classes is that they are more complex. There is the hidden reference to the outer class (maybe even more than one). And a simple name in a method of the inner class may now be one of three things: a local, a field, or a field of an outer class.
An artifact of that complexity is that the hidden reference to the outer class can lead to memory leaks. Say the inner class is a listener and could be a static inner class. As long as the listener is registered, it holds a reference to the instance of the outer class, which may in turn hold on to large amounts of memory. Making the listener static may allow the outer instance to be garbage collected.
A Non-static inner class has an implicit reference to outer class. If you make the class as static, you could save some memory and code.
Benefits of static inner classes:
Instantiation of static inner class does not rely on external class guidance, and the memory overhead of instantiation.
Static inner class does not hold external class guidance, does not affect the collection of external class, to avoid the extension of the external class in memory survival time leading to memory leakage.
We already have good answers, here are my 5 cents:
Both static and non-static inner classes are used when we need to separate logical functionalities yet using the methods and variables of the outer class. Both of the inner classes have access to the private variables of the outer class.
Advantages of static inner class:
1) static classes can access the static variables from outer class
2) static classes can be treated like an independent class
Non-static inner class:
1) cannot use static members of the outer class
2) cannot be treated like an independent class
public class NestedClassDemo {
private int a = 100;
int b = 200;
private static int c = 500;
public NestedClassDemo() {
TestInnerStatic teststat = new TestInnerStatic();
System.out.println("const of NestedClassDemo, a is:"+a+", b is:"+b+".."+teststat.teststat_a);
}
public String getTask1(){
return new TestInnerClass().getTask1();
}
public String getTask2(){
return getTask1();
}
class TestInnerClass{
int test_a = 10;
TestInnerClass() {
System.out.println("const of testinner private member of outerlcass"+a+"..."+c);
}
String getTask1(){
return "task1 from inner:"+test_a+","+a;
}
}
static class TestInnerStatic{
int teststat_a = 20;
public TestInnerStatic() {
System.out.println("const of testinnerstat:"+teststat_a+" member of outer:"+c);
}
String getTask1stat(){
return "task1 from inner stat:"+teststat_a+","+c;
}
}
public static void main(String[] args){
TestInnerStatic teststat = new TestInnerStatic();
System.out.println(teststat.teststat_a);
NestedClassDemo nestdemo = new NestedClassDemo();
System.out.println(nestdemo.getTask1()+"...."+nestdemo.getTask2());
}
}
Accessing the static inner and non-static inner class from outside:
public class TestClass {
public static void main(String[] args){
NestedClassDemo.TestInnerClass a = new NestedClassDemo().new TestInnerClass();
NestedClassDemo.TestInnerStatic b = new NestedClassDemo.TestInnerStatic();
}
}
The official java doc for static inner class can be found at https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
public static class ViewHolder {
public int a,b;
public void method();
}
are the method and the variables a and b by default static when I declare the class as static or do I have to separately declare them static ? I know its a noobish question but I am a little confused right now :(
No, they're not static by default, they're normal instance members.
Static inner classes, unlike normal inner classes, can have static members, though, if you explicitly declare them.
No, when you declare an inner static class you specify that the declaration itself is static, so that you don't need an object instance of the parent class to access it.
Nothing regarding inner members is involed.
The members of the Static nested class are not static. static keyword is specified with the class which signifies that the nested class can be instantiated with the containing outer class similar to static data member.
BaseClass.StaticNestedClass nestedClass = new BaseClass.StaticNestedClass();
nestedClass.nonStaticMethod();//correct
BaseClass.StaticNestedClass.nonStaticMethod()//Error
This has no effect on the data members of the static nested class which behave as normal class.
Please note if a static keyword is associated with a class then the class has to be a nested class
A public static class works just like any other class. The only real difference is that it is accessed through the containing class:
OuterClass.InnerClass foo = new OuterClass.InnerClass();