How to access outer class method local variable in local inner class? - java

public class MyClass {
int x=9;
public static void main(String args[]) {
MyClass myClass = new MyClass();
myClass.test();
}
public void test(){
int x=10;
class InnerClass{
int x = 11;
void print(){
int x = 12;
System.out.println(x);
System.out.println(this.x);
System.out.println(MyClass.this.x);
System.out.println("MyClass => test() => x :" + "?");
}
}
InnerClass innerClass = new InnerClass();
innerClass.print();
}
}
How to call MyClass test() method local variable x inside the InnerClass print() method. What i can write in place of ? in last System.out.println() method in order to get the value of test() x.

Unfortunately in Java you can't.
The only way to access the x in MyClass::test would be to rename both variables in your inner class and in your inner class method into something else.
There is no need though to rename the outer class field x as InnerClass::print would consider the variable in the most-inner scope.
Although this snippet is for demonstration purposes, better practice would have you have different and more significant names for each variable.

That works fine for me:
public class Outerclass {
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.outerMethod();
}
// method of the outer class
void outerMethod() {
int num = 23;
// method-local inner class
class MethodInnerClass {
public void print() {
System.out.println("This is method inner class "+num);
}
}
// Accessing the inner class
MethodInnerClass inner = new MethodInnerClass();
inner.print();
}
}

To print outer class variable use
MyClass.this.x

Related

Is there any way to create object of method-local inner class in main method?

I was wondering if there is any way to create a method-local inner class object in main() method with the help of Outerclass object.
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// method-local inner class
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
} // end of inner class
// Accessing the inner class
MethodInner_Demo inner = new MethodInner_Demo();
inner.print();
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
}
}
Edit-1:
I was exploring the way to instantiate a method-local inner class in the main method ( I know the method-local inner class is not visible to the main method) but still, is there any workaround?
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// method-local inner class
class MethodInner_Demo {
public void print() {
System.out.println("This is method inner class "+num);
}
} // end of inner class
}
public static void main(String args[]) {
Outerclass outer = new Outerclass();
//inner-class object is created while calling my_Method()
// TBH IDK how to do this
outer.my_Method().new MethodInner_Demo();
}
}
Class MethodInner_Demo is a local class, not an inner class, since it is declared in the body of a method. See e.g. The Java™ Tutorials.
A local class can only be seen by code in the method where is it declared.
If you want to be able to create an instance of the class from another method, then you need to move the class outside the method, so it becomes an actual inner class.
You can then create an instance, assuming you're "authorized", as defined by the public, protected, and private access modifiers. You do that by qualifying the new operator with an instance of the outer class.
In your case, we also need to add a field to carry the value of num.
public class Outerclass {
// instance method of the outer class
void my_Method() {
int num = 23;
// Accessing the inner class
Inner_Demo inner = new Inner_Demo(num);
inner.print();
}
// inner class
class Inner_Demo {
private final int num;
Inner_Demo(int num) {
this.num = num;
}
public void print() {
System.out.println("This is inner class "+num);
}
} // end of inner class
public static void main(String args[]) {
Outerclass outer = new Outerclass();
outer.my_Method();
// Accessing the inner class
int num = 42;
Inner_Demo inner = outer.new Inner_Demo(num);
inner.print();
}
}
The type of the method local class is invisible to main. However, you can create that instance and pass it to main.
public class OuterClass {
Object createInnerClass() {
int num = 23;
class InnerClass {
#Override
public String toString() {
return "I'm InnerClass. num=" + num;
}
}
return new InnerClass();
}
public static void main(String args[]) {
OuterClass outer = new OuterClass();
Object obj = outer.createInnerClass();
System.out.println(obj);
}
}
output:
I'm InnerClass. num=23

Method Local Inner classes program

I am just learning Java concepts.
Can anyone let me know why i am not able to run this program?
package innerClasses;
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
class Inner {
public void m2() {
System.out.println(i);
}
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
}
}
Can anyone let me know why i am not able to run this program?
The most basic reason is because of scope. In order to do
Test.Inner in = t.new Inner();
Inner must be defined in Test, but it is instead defined in m1 scope.
The class Inner is declared inside the method m1(), what makes it not available outside this method.
Your code has to look like the following to be able to run, although it will not print anything...
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
}
class Inner {
public void m2() {
System.out.println(i);
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
}
}
Replacing t.m1(); by in.m2(); will output 10.
EDIT
In case you have to create the inner class inside the method, make it like
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
class Inner {
public void m2() {
System.out.println(i);
}
}
// this is what makes it run
Inner myInner = new Inner();
myInner.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1();
}
}
to compile and run.
IMHO this is not a good way to go...
A method inner class is only visible to that method only so you can't use this at any other location.
for using this class you have to declare it outside of the method.
You cannot compile it as the scope of Inner class is the m1 method.
If you want to be able to create instances of Inner class you can define it directly inside the Test:
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
}
// On the Test class level
class Inner {
public void m2() {
System.out.println(i);
}
}
public static void main(String[] args) {
Test t = new Test();
Test.Inner in = t.new Inner();
t.m1();
in.m2(); // prints 10
}
}
Another feature provided by Java is to use anonymous classes. It can be created by implementation of some Interface:
// Define an interface to be able to implement it inside the method
interface Inner {
void m2();
}
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
// Implement interface and call method on it
// Functional style:
((Inner) () -> System.out.println(i)).m2();
// Legacy style:
new Inner() {
#Override
public void m2() {
System.out.println(i);
}
}.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1(); // prints 10 twice
}
}
or extending some class:
// A class we going to extend
class Inner {
void m2() {
System.out.println(11);
}
}
public class Test {
int i=10;
static int j=20;
public void m1() {
int k=30;
final int m=40;
// Extend inner class and call method on it
new Inner() {
void m2() {
System.out.println(i);
}
}.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1(); // prints 10, not 11
}
}
So the best way for you depends on what code design do you want to get finally.
Your class Inner is what the JLS calls a Local Class (14.3. Local Class Declarations).
The scope of a Local Class is defined as (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.
The scope of a local class declaration immediately enclosed by a switch block statement group (§14.11) is the rest of the immediately enclosing switch block statement group, including its own class declaration.
In your case it is declared in a block, which is the body of your method. So the scope where your class is visible is the rest of this method body.
As the type Inner is not visible in main(), you cannot use it there. You could create instances of it and use them within m1(), though.
The very basic reason for compile time error is "Scope".
As per your code, class Inner is defined inside method m1 (this class is called Local class/method local class),so if you observe the scope of method variable, its within the declared method only and we cannot access any method variable outside that method and this is reason, the scope of class Inner is limited to the m1 method
so if you want to instantiate class Inner and invoke its methods then you must do it in m1 method (in code , you are trying to create class Inner object outside method m1, which is not possible) hence the code would be
public class Test {
int i = 10;
static int j = 20;
public void m1() {
int k = 30;
final int m = 40;
class Inner {
public void m2() {
System.out.println(i);
}
}
Inner in = new Inner();
in.m2();
}
public static void main(String[] args) {
Test t = new Test();
t.m1();
}
}
some more info , the local classes can be used when any repeated functionality is required inside a method (as nested methods are not allowed in java, so we can create inner class) and off course if we are not interested to create class level method for example
class Outer {
public void cal() {
class Inner {
public void sum(int x, int y) {
System.out.println("sum : "+(x+y));
}
}
Inner i= new Inner();
i.sum(10, 20); //sum is repeatdly needed in between code
i.sum(100, 200);
i.sum(1000, 2000);
i.sum(10000, 20000);
}
}
public class TestClass {
public static void main(String[] args) {
new Outer().cal();
}
}

How to access a method of Extended Class from nested class?

I have two nested classes inside a class with the outer class extending another class. The structure is something like this.
public class EXTENSION_CLASS
{
public int Get_Value()
{
return(100);
}
}
public class OUTER extends EXTENSION_CLASS
{
public static class NESTED1
{
public void Method1()
{
int value=0;
value=Get_Value();
System.out.println("Method1: "+value);
}
}
public static class NESTED2
{
NESTED1 Nested1_Instance=new NESTED1();
public void Method2()
{
Nested1_Instance.Method1();
}
}
public void run()
{
NESTED2 Nested2_Instance=new NESTED2();
Nested2_Instance.Method2();
}
public static void main (String[] args)
{
OUTER New_Class=new OUTER();
New_Class.run();
}
}
I'm expecting the output: "Method1: 100". But, am getting the output: "OUTER.java:16: error: non-static method Get_Value() cannot be referenced from a static context value=Get_Value();". How can i make this working?
Cheers !
Rajesh.
Remove the static modifier from the declaration of NESTED1 and NESTED2, like so:
public class NESTED1
If you want keep the nested classes static, you will have to create an instance of OUTER in the Method1() to access Get_Value().
public void Method1()
{
int value=0;
OUTER outer = new OUTER();
value=outer.Get_Value();
System.out.println("Method1: "+value);
}
You're trying to make a static reference to a non-static member.
This means that you're trying to access a instance member from a static member of the class.
To fix the issue, remove the static modifier from both the NESTED1 and NESTED2 clases.
Alternately, if you do not wish to remove the static modifier, you will have to create an object of the OUTER or EXTENSION_CLASS classes and then invoke Get_Value() using the object.
For example:
public void Method1()
{
int value=0;
EXTENSION_CLASS ext = new EXTENSION_CLASS ();
value=ext.Get_Value();
System.out.println("Method1: "+value);
}
OR
public void Method1()
{
int value=0;
OUTER outer = new OUTER();
value=outer.Get_Value();
System.out.println("Method1: "+value);
}
The error says every thing. You can not call non-static methods from static methods / class.
To make it work, Simply add static keyword to 'Get_Value' method in EXTENSION_CLASS.

Static block is not getting executed in case of anonymous objects

Why doesn't a static block in the class get executed when I don't create a reference variable for an object (anonymous) of that class?
For example, let us consider this simple class:
public class StaticDemo {
private static int x;
public static void display(){
System.out.println("Static Method: x = "+x);
}
static {
System.out.println("Static Block inside class");
}
public StaticDemo(){
System.out.println("Object created.");
}
}
Another class using it:
public class UseStaticDemo {
public static void main(String[] args) {
StaticDemo Obj = new StaticDemo();
Obj.display();
System.out.println("------------");
new StaticDemo().display();
}
}
Output:
Static Block inside class
Object created.
Static Method: x = 0
------------
Object created.
Static Method: x = 0
A static initializer block only runs once, when the class is loaded and initialized.
Also, static methods have absolutely no relation to any instances. Doing
new StaticDemo().display();
is pointless and unclear.

Instantiate inner class object from current outer class object

I am wondering if the following is valid in Java:
class OuterClass {
OuterClass(param1, param2) {
...some initialization code...
}
void do {
// Here is where the doubt lays
OuterClass.InnerClass ic = this.new InnerClass();
}
class InnerClass {
}
}
Basically what I am trying to achieve here is to instantiate an inner class object from the current instance of the outer class, not a new instance, the current one. I believe this comes handy is when the constructor of the outer class is not empty (takes parameters) and we don't know what pass to them (they can't be null since some might be assigned to a class variable that is accessed by the inner class object).
Let me know if I explained myself well.
Thanks in advance!
Regarding:
public class OuterClass {
OuterClass() {
// ...some initialization code...
}
void doSomething() {
OuterClass.InnerClass ic = this.new InnerClass();
}
class InnerClass {
}
You don't need the explicit OuterClass identifier nor the this as they're implied.
So this is unnecessary:
OuterClass.InnerClass ic = this.new InnerClass();
And this is fine inside of an instance method:
InnerClass ic = new InnerClass();
Things get dicier though if you're creating an object of InnerClass in a static method such as main that is held inside of OuterClass. There you'll need to be more explicit:
This won't work
public class OuterClass {
public static void main(String[] args) {
InnerClass otherInnerVar = new InnerClass(); // won't work
}
But this will work fine:
public class OuterClass {
public static void main(String[] args) {
InnerClass otherInnerVar2 = new OuterClass().new InnerClass(); // will work
}
Every instance of an inner class, unless the Class is declared as static, must have a 'connected' instance of an outer class, in order to be instantiated.
This won't work:
public class Outer {
public class Inner {
}
public static void main(String[] args) {
Inner inner = new Inner(); //compilation error
}
}
However, this will work, it doesn't need an instance of Outer, since the static keyword is used:
public class Outer {
public static class Inner {
}
public static void main(String[] args) {
Inner inner = new Inner();
}
}
more info: java inner classes
Above is the example for creating Inner class object inside outer class and outside outer class:
public class OuterClass {
public class InnerClass{
public void myMethod(){
System.out.println("inside inner class");
}
}
public void myMethod(){
System.out.println("outer class method");
InnerClass class1 = new InnerClass();
class1.myMethod();
}
public static void main(String[] args){
//OuterClass.InnerClass class1 = new OuterClass().i
OuterClass outerClassObj = new OuterClass();
OuterClass.InnerClass innerClassObj = outerClassObj.new InnerClass();
innerClassObj.myMethod();
}
}

Categories