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.
Related
I'm studying inner classes in java. I have seen that if inner class is non static then it can easily access the outer class variable. But what if inner class is static, then how can we take a access of outer class's variable using static's class object ?
Below is my code, where am accessing outer class variable from inner class
package org;
public class Outerclass {
String name = "Europe";
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
static class innerclass {
void updatename() {
Outerclass o = new Outerclass();
o.setname("USA");
}
}
public static void main(String[] args) {
Outerclass b = new Outerclass();
b.name; // why this error here ? "Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
innerclass i = new innerclass();
i.updatename();
}
}
You can't access non-static contents inside the static content
When we create static inner class by default it will created as a outer template as a association of inner template. So we can load both together but only static things can be inside the static inner class.
Now there are no connection between objects of the classes. But there are connection between the templates.
Following is your code I have done some modification might help you
public class Demo {
String name = "Europe";
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
System.out.println(this.name);
}
static class innerclass {
void updatename() {
Demo o = new Demo();
o.setname("USA");
}
}
public static void main(String[] args) {
Demo b = new Demo();
String a = b.name; // why this error here ? "Syntax error, insert "VariableDeclarators" to complete LocalVariableDeclaration"
System.out.println(a);
innerclass i = new innerclass();
i.updatename();
}
}
Inner static class behives same as normal class:
can access static property/method of outer class
can't non-access static / methods of outre class directly, they will require an outerclass instance reference to do so.
it does not rquire an instance of outer class to be created
It is used mostly in two scenarios:
you are creating a group of classes with similar nature/function, and you want to keep them under one 'Napespace'
you want to create a private class that will not be visible to anyone, except to outter class (private static inner class). That way you can create interface implementations visible only to your outer class.
Non-static inner class:
it requires instance of outer class to be created
it can access methods and properties of outer class.
Quote:
...inner classes can access all members of the declaring class, even
private members. In fact, the inner class itself is said to be a
member of the class; therefore, following the rules of object-oriented
engineering, it should have access to all members of the class.
I read that an instance of an inner class cannot be created without an instance of outer class. But when I tried to create an instance of my inner class using it as an instance member of my outer class, it worked.
I understand that it is creating an inner object through a reference to my outer class object, but is it the right way to do it?
Below is my code snippet:
public class TestInner {
private Nonstatic non = null;
private static int access = 4;
public class Nonstatic {
void hello() {
access = 90;
}
}
public static void main(String[] args) {
TestInner outer = new TestInner();
TestInner.Nonstatic innern= outer.new Nonstatic();
System.out.println("Non static obj1 is "+innern);
outer.testinnerObj();
}
public void testinnerObj() {
non = new Nonstatic();
System.out.println("Non static obj2 is "+non);
non.hello();
}
}
You're writing "An instance of Inner class cannot be created without an instance of outer class". And that's exactly what you are doing.
First, you create an instance of the "outer" class:
TestInner outer = new TestInner();
Then, you create an instance of the "inner" class - it only lives
in the scope of outer:
TestInner.Nonstatic innern= outer.new Nonstatic();
So, the question maybe boils down to this: yes, you are creating the object in the static main method. But that does not matter, because you are using the syntax outer.newwhich creates it in the scope of outer.
Hope that helps.
I have read this concept in respect to static inner class : ViewHolder declared as inner class inside the adapter of ListView to enhance the performance of getView().
Consider the below class
public class OuterClass{
public class InnerClass{
private int privateProperty= -2;
}
public static void main(String[] args) {
OuterClass oc = new OuterClass();
InnerClass ic = oc.new InnerClass();
ic.privateProperty = -98;
}
}
If inner class contains private properties and an object of inner class is created inside a method of outer class then the inner class private properties can be accessed directly using . 'dot' operator.
I have read somewhere that the private properties of the inner class are accessed using synthetic setter getter methods from outer class
I want to clear my concept regarding the same.
The compiler generates method to access private members of an inner class. If you compile your example code and examine the bytecode, you will find that it is as if it were written like this:
public class OuterClass{
public class InnerClass{
private int privateProperty= -2;
static int access$002(InnerClass obj, int value) {
obj.privateProperty = value;
return value;
}
}
public static void main(String[] args) {
OuterClass oc = new OuterClass();
InnerClass ic = oc.new InnerClass();
InnerClass.access$002(ic, -98);
}
}
This conversion of the line
ic.privateProperty = -98;
into the method call:
InnerClass.access$002(ic, -98);
together with the creation of the static method InnerClass.access$002 is done by the compiler. The static method (named access$002 by my compiler) is an example of a "synthetic setter method" you have read about. As a result, the bytecode for the two classes do not violate Java's access rules.
Your concept is wrong.. Inner classes are meant to use inside the container classes only, This idea coming from the concept that you don't want to expose unnecessery classes to the developer, Which is not relevant to all of the project.
In this case InnerClass will be related to only to OuterClass. In the main you should create new only to OuterClasS and the OuterClass will create instance of InnerClass
So it should be something like this:
public class OuterClass{
private InnerClass in;
public Class OuterClass() {
in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
in.setPrivateProperty(x);
}
public class InnerClass{
private int privateProperty= -2;
//getters & setters
}
public static void main(String[] args) {
OuterClass oc = new OuterClass();
oc.setInnerProperty(98);
}
}
In case you want to change it from the main.. This is the way to do it, but not recomended.
Hope that helps
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.
I encounter the following question in Java, how to initialize an instance of inner class if the inner class is declared in the method of outer class? I met an compile error in the following case. Many thanks.
class Outer {
public int a = 1;
private int b = 2;
public void method(final int c){
int d = 3;
class Inner{
private void iMethod(int e){
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("e = " + e);
}
}
}
public static void main (String[] args){
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();// there is an compile error here
}
}
how to initialize an instance of inner class if the inner class is declared in the method of outer class?
You can't. The scope of the class is confined to the method itself. It's similar to why you can't access local variables outside the method.
From JLS §6.3 - Scope of a Declaration:
The scope of a local class declaration immediately enclosed by a block (§14.2) is the rest of the immediately enclosing block, including its own class declaration.
You cannot. The Inner class is local to the method(int) method.
If you want to access it, you will need to declare it in a larger scope.
In a sick twist of fate, you can use reflection to get an instance. Take for example
package com.so.examples;
class Main {
public void method(final int c){
class Inner{
public Inner() {}
private void iMethod(int e){
System.out.println("inner method");
}
}
}
public static void main (String[] args) throws Exception{
Class clazz = Class.forName("com.so.examples.Main$1Inner");
Constructor<?> constructor = clazz.getConstructor(new Class[]{Main.class});
Object instance = constructor.newInstance(new Main());
System.out.println(instance.getClass());
}
}
This prints out
class com.so.examples.Main$1Inner
Without reflection, you cannot access any of its members because you cannot declare a variable of type Inner outside of the method.