This may be silly to ask, but looking at following code raises a question.
public class Outer {
public class Inner {
public static final int variable = 100;
}
public static void main(String[] args) {
int test = Outer.Inner.variable; // Inner Non-Static accessed
// with Class reference?
}
}
How can the non-static nested class be accessed with a class reference?
The variable is static, and that is what matters. Since the variable is static you can always access it with the class reference.
Related
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());
}
For example I've got simple class
class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + obj.i);
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Why I can get access to i in static method?
private members can be accessible with in the class. Your static method belongs to the same class. Hence you can access.
Modifier Class Package Subclass World
---------------------------------------------
private **Y** N N N
Update: To avoid the confusion, move the static method to other class and try once.
Don't get confused with static and private/public/[default]. Those are two separate things. A static function can access private non-static field because it is part of the class. And thats whats private does, only restricting access to the class level, without any distinction being made between static or not.
If it's the staticness that's bothering you, obj is a proper "not static" object, which us why it has an accessible non-static field. The method being static is irrelevant.
you are accessing instance of object not directly class variable. when you use direly "i" without reference to object its not allowed.
Private variable visibility is by default in with in class access .
public class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + i); //compile Error ::Cannot make a static reference to the non-static field i
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a question about this topic:
An instance by a inner class need everytime an object of the same type of the guest class of the inner class. example:
public class GuestClass {
class innerClass {
}
public static void main(String[] args) {
innerClass test = new innerClass(); //does not work because
//I need a object of type GuestClass
GuestClass iNeedYou = new GuestClass();
innerClass nestClassObj = iNeedYou.new innerClass(); //it works
}
}
ok it's clear.
the innerClass object now points also to an GuestClass object (iNeedYou)
Now come my question:
an anonymous class is also a inner class right?
but with some difference:
A. I don't know the type of this object
B. it implements an interface.
but it is still an object by an inner class (anonymus but inner)
in fact if I do this:
public class GuestClass {
private int numb = 100;
class innerClass {
}
public void createAnAnonymusObject () {
myInterface myAnObj = new myInterface(){
int a, b;
#Override
public void print() {
System.out.println(numb); //it works
}};
myAnObj.print();
}
public static void main(String[] args) {
GuestClass iNeedYou = new GuestClass();
iNeedYou.createAnAnonymusObject();
}
}
works because the anonymous inner object points to the outer object... so i can see the variable numb.
but why this works?
public static void main(String[] args) {
myInterface myAnObj = new myInterface(){ //why does it work? in this case
//where is the outer object?
int a, b;
#Override
public void print() {
}};
}
if the anonymous class is an inner class why it doesn't need an outer object?
You're basically asking two questions here.
Why does a non-static nested class require an enclosing instance?
Because it's assumed to have access to all non-static members of the outer class. Even if you don't actually use any of those, the compiler can't infer that the non-static nested class can be used safely in static context. You have to explicitly mark it static to allow this.
Where and what is the enclosing object of the anonymous class created in this snippet?
public class OuterClass {
private int nonStaticMember;
private static int staticMember;
public static void main(String[] args) {
MyInterface myAnObj = new MyInterface(){ //why it works ?? in this case
//where is the outer object?
#Override
public void print() {
//nonStaticMember is not visible in this scope
//staticMember is visible in this scope
}};
}
}
In this case, your anonymous class has no enclosing instance. It's created in a static context, in the main method. You can instantiate MyInterface because all interfaces are implicitly static, even if defined inside another class. That's why the interface is visible at all. All of the non-static members of OuterClass, on the other hand, are not available in this scope so you're guaranteed not to use any of them. This is why there is no need to have a reference to an enclosing object. In fact, this is included in the language's specification.
Take a look at this Java Language Standard excerpt
Let C be the class being instantiated, and let i be the instance being
created. If C is an inner class then i may have an immediately
enclosing instance. The immediately enclosing instance of i (§8.1.3)
is determined as follows.
If C is an anonymous class, then:
If the class instance creation expression occurs in a static context
(§8.1.3), then i has no immediately enclosing instance.
Otherwise, the immediately enclosing instance of i is this.
(...)
I only quoted the most relevant part for this use case. Feel free to dive a little deeper into it.
public class Anonymous2 {
private int numb = 100;
public static void main(String[] args) {
MyInterface myAnObj = new MyInterface(){ //why it works ?? in this case
//where is the outer object?
int a, b;
#Override
public void print() {
System.out.println(numb);
}};
}
}
interface MyInterface {
public void print();
}
Compiling:
C:\JavaTools>javac Anonymous2.java
Anonymous2.java:11: error: non-static variable numb cannot be referenced from a static context
System.out.println(numb);
^
1 error
As can be seen, the code that the OP claimed would compile doesn't. So this entire question is irrelevant.
Here is the code where I am updating the instance variable x of OuterClass by static variable of StaticInner. I understand that the static inner classes cannot refer directly to instance variable of outer classes. I am using an instance of outerclass to refer to its instance variable 'x' and update it. This goes into stackoverflow error. The code complies fine. The last line in the code does not compile which I commented out. I don't understand what the problem with that line.
public class OuterClass {
private int x = 10;
private static int y = 15;
private static StaticInner si=null;
public OuterClass() {
setStaticInner();
this.x=si.ic.x;
}
public static class StaticInner {
private static int z = 20;
private OuterClass ic = new OuterClass();
public void increment() {
OuterClass.y+=z;
z+=OuterClass.y;
ic.x+=10;
}
}
public void setStaticInner(){
si=new StaticInner();
}
public static void main(String[] args){
OuterClass ic = new OuterClass();
ic.si.increment();
System.out.println(ic.x);
//OuterClass.StaticInner sb1 = ic.new StaticInner(); This line does not compile.
}
}
You have a circular dependency in the constructors, resulting in a recursive call between them
Outer(){
createInner()
}
Inner(){
createOuter()
}
This won't work (unless you use reflection, but that defeats the purpose).
You need to structure the classes so there is a linear dependency. I recommend passing the outer instance to the inner constructor
Outer(){
inner = new Inner(this);
}
Inner(Outer o){
myouter = o;
}
Don't qualify "new" with an outer class instance. That only applies to inner classes. Just instantiate the nested class like any other.
You should not need to mention the outer class at all when working with a static nested class inside the outer class.
Why can we have static final members but cant have static method in an non static inner class ?
Can we access static final member variables of inner class outside the outer class without instantiating inner class ?
YOU CAN have static method in a static "inner" class.
public class Outer {
static String world() {
return "world!";
}
static class Inner {
static String helloWorld() {
return "Hello " + Outer.world();
}
}
public static void main(String args[]) {
System.out.println(Outer.Inner.helloWorld());
// prints "Hello world!"
}
}
To be precise, however, Inner is called a nested class according to JLS terminology (8.1.3):
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.
Also, it's NOT exactly true that an inner class can have static final members; to be more precise, they also have to be compile-time constants. The following example illustrates the difference:
public class InnerStaticFinal {
class InnerWithConstant {
static final int n = 0;
// OKAY! Compile-time constant!
}
class InnerWithNotConstant {
static final Integer n = 0;
// DOESN'T COMPILE! Not a constant!
}
}
The reason why compile-time constants are allowed in this context is obvious: they are inlined at compile time.