I have code like this I need to access the mysample variable of static class InnerClass in the getInnerS() method which is inside the the NestedClass. I tried accessing it by creating a new object for InnerClass but i am getting java.lang.StackOverflowError.
public class NestedClass{
private String outer = "Outer Class"; //NestedClass instance variable
NestedClass.InnerClass innerClass = new NestedClass.InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(innerClass.mysample);
}
static class InnerClass{
private String mysample = "Inner Class"; //InnerClass instance variable,
NestedClass a = new NestedClass();
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(a.outer);
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = new NestedClass.InnerClass();
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
In InnerClass constructor:
NestedClass a = new NestedClass();
So, you create a new NestedClass, which creates a new InnerClass, which creates itself its own NestedClass, with the corresponding InnerClass.... No wonder the stackoverflow.
If you want to access the enclosing class, you should use (inside InnerClass methods)
NestedClass.this
NestedClass a = new NestedClass();
in static InnerClass class creates an instance of the NestedClass and as InnerClass is static this is a loop.
InnerClass does not need to be static, this should work
public class NestedClass {
private String outer = "Outer Class"; //NestedClass instance variable
NestedClass.InnerClass innerClass = new NestedClass.InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(innerClass.mysample);
}
class InnerClass{
private String mysample = "Inner Class"; //InnerClass instance variable,
NestedClass a = NestedClass.this;
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(a.outer);
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = nestedClass.innerClass;
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
With this solution member class is static. For better comparison you might read
Static class declarations
Static nested classes (description)
Static nested classes do not have access to non-static fields and methods of the outer class, which in some ways similar to the static methods defined within the class. Access to non-static fields and methods can only be done through an instance reference of the outer class. In this regard, static nested classes are very similar to any other top-level classes.
In addition, static nested classes have access to any static methods of the outer class, including to private.
The benefits of these classes is mainly in logical groupings of entities to improve encapsulation, as well as saving class-space.
public class NestedClass{
private static String outer = "Outer Class"; //NestedClass instance variable
InnerClass innerClass = new InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(InnerClass.mysample);
}
InnerClass getInner(){
return innerClass;
}
static class InnerClass{
private static String mysample = "Inner Class"; //InnerClass instance variable,
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(outer); //access a static member
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = nestedClass.getInner();
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
Related
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
I can understand why inner class can access outer class private members, but its not clear why instance of inner class defined in outer class method can access inner class private members. For example: the following code works fine.
class OuterClass
{
int outer_default;
private int outer_private;
protected int outer_protected;
static int outer_static;
static {
outer_static=5;
}
public OuterClass()
{
outer_default=1;
outer_private=2;
outer_protected=3;
System.out.println("Outerclass object created!!!!");
}
public void outerMethod()
{
System.out.println("**********Outerclass accessing outer class members********************");
System.out.println("outerdefault: "+outer_default);
System.out.println("outerprivate: "+outer_private);
System.out.println("outerprotected: "+outer_protected);
System.out.println("outerstatic: "+outer_static);
System.out.println("**************************************************************");
InnerClass innerObj = new InnerClass();
System.out.println("**********Outerclass accessing inner class members********************");
System.out.println("innerdefault: "+innerObj.inner_default);
System.out.println("innerprivate: "+innerObj.inner_private); //HOW IS THIS POSSIBLE??????
System.out.println("innerprotected: "+innerObj.inner_protected);
System.out.println("**************************************************************");
}
class InnerClass
{
int inner_default;
private int inner_private;
protected int inner_protected;
public InnerClass()
{
inner_default=4;
inner_private=5;
inner_protected=3;
System.out.println("Innerclass object created!!!!");
}
public void innerMethod()
{
System.out.println("**********Innerclass accessing inner class members********************");
System.out.println("innerdefault: "+inner_default);
System.out.println("innerprivate: "+inner_private);
System.out.println("innerprotected: "+inner_protected);
System.out.println("**************************************************************");
System.out.println("**********Innerclass accessing outer class members********************");
System.out.println("outerdefault: "+outer_default);
System.out.println("outerprivate: "+outer_private);
System.out.println("outerprotected: "+outer_protected);
System.out.println("outerstatic: "+outer_static);
System.out.println("**************************************************************");
}
}
}
class Main {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
OuterClass.InnerClass inner = outer.new InnerClass();
inner.innerMethod();
}
}
I have commented near the code in which I have doubt.
I have a following code
class OuterClass<T>{
class Innerclass{
int k;
}
public static void main(String argv[]){
OuterClass<Integer> out =new OuterClass<>();
Innerclass in; // errors out
}
}
But for a class with no generics like the following code, I could create object for inner class.
class OuterClass{
class Innerclass{
int k;
}
public static void main(String argv[]){
OuterClass out =new OuterClass();
Innerclass in; // No error
}
}
why am i not able to create object of inner class though no generics are used in the inner class in my first example? Please explain.
Your main method belongs to OuterClass and is static in there. Since InnerClass is not a static class but implicitly depends on the generic type T (the generic type is available in the inner class, even if your example isn't using it), you cannot reference it from a static method.
In other words, since InnerClass depends on the generic type, you cannot break it "lose" from OuterClass and use it outside of it.
If your inner class won't depend on the generic type, you can just make it static. However, you might want to consider just extracting it into a separate class rather than nesting classes in this case:
class OuterClass<T> {
static class InnerClass {
int k;
}
public static void main( String argv[] ) {
InnerClass inner = new InnerClass();
}
}
If the generic is important for the inner class, you can tell the compiler which generic to infer for the outer class by specifying it (note that the generic type of outer and inner must match) or by using OuterClass.InnerClass in which case the compiler will use the raw type:
class OuterClass<T> {
class InnerClass {
int k;
}
public static void main( String argv[] ) {
OuterClass<String> outer = new OuterClass<String>();
// works and has the "correct" generic type
OuterClass<String>.InnerClass inner1 = outer.new InnerClass();
// works, but uses the raw type
OuterClass.InnerClass inner2 = outer.new InnerClass();
}
}
Note that you need an enclosing instance outer of type OuterClass<T> in order to instantiate InnerClass (since the class is not static, it belongs to an instance of OuterClass).
This also goes for the example without generics: you will need an enclosing instance to instantiate the inner class, so
class OuterClass {
class InnerClass {
int k;
}
public static void main( String argv[] ) {
OuterClass outer = new OuterClass();
InnerClass in = outer.new InnerClass();
}
}
will work while
class OuterClass {
class InnerClass {
int k;
}
public static void main( String argv[] ) {
OuterClass outer = new OuterClass();
InnerClass in = new InnerClass();
}
}
won't.
What is the example of indirect access to private member of superclass from subclass?
A nested class has access to all the private members of its enclosing
class—both fields and methods. Therefore, a public or protected nested
class inherited by a subclass has indirect access to all of the
private members of the superclass.
Quote from http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
In the quote, we talk about "nested" class
here is an example of how an inner class can access private fields of the outer class.
class OuterClass {
private int x = 7;
public void makeInner(){
InnerClass in = new InnerClass();
in.seeOuter();
}
class InnerClass {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
public static void main(String[] args) {
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
inner.seeOuter();
}
}
Finally, if you extend a class with the InnerClass, they will also access the private fields of the OuterClass if your InnerClass is public or protected
It is to be supposed (but the compiler does not enforce it, only warns), that a private method will end being used by a public, protected or default method (otherwise it is useless).
So, the extending class can "indirectly" call the private method by calling the public, protected or default method that ends calling the private method.
Yes, we can access private members of a superclass in the child class through the public method of the superclass which can be invoked from the child class's reference variable heaving the reference id of child class.
for example:-
class Base
{
private int x=10;
void show()
{
System.out.println(x);
}
}
class Child extends Base
{
public static void main(String... s)// public static void main(String[] args)
{
//rom jdk 1.7 main can be defined like above
Child c=new Child();
c.show();
}
}
The output will be 10
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();
}
}