Create array of inner class object in a different class - java

Consider the following nested classes.
class Outerclass {
class innerclass {
}
}
class util {
//how to declare an array of innerclass objects here?
}

You can declare an array of innerclass objects like this.
class util {
Outerclass.innerclass[] inner = new Outerclass.innerclass[10];
}
And to instantiate them you can do something like this inside the util class.
void test() {
Outerclass outer = new Outerclass();
inner[0] = outer.new innerclass();
}

OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerArray[] = new OuterClass.InnerClass[3];
// Creating Objects of Inner Class
OuterClass.InnerClass innerObject1 = outerObject.new InnerClass();
OuterClass.InnerClass innerObject2 = outerObject.new InnerClass();
OuterClass.InnerClass innerObject3 = outerObject.new InnerClass();
// Adding the Objects to the Array
innerArray[0] = innerObject1;
innerArray[1] = innerObject2;
innerArray[2] = innerObject3;

Related

How instantiating an inner class in Java really works?

I'm making an instance from an inner class, but I can't understand what does this syntax mean.
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
I know that I can't get an object from an inner class without getting an object from the outer one OuterClass outerObject = new OuterClass();, then we use the object from the outer class outerObject to get an instance from the inner class outerObject.new InnerClass();, so what does OuterClass.InnerClass actually means as it is not explained in the Java documentation as it states:
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax OuterClass.InnerClass innerObject = outerObject.new InnerClass();
If I recall correctly, the syntactic meaning is as follows:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
InnerClass The class InnerClass
. which is an inner class of
OuterClass OuterClass
innerObject has an instance named innerObject
= which is assigned the value
new InnerClass() of a new InnerClass instance
. such that when you use
OuterClass.this from within
InnerClass methods invoked on
innerObject, it refers to
outerObject outerObject.
The key here is that inner classes are created through a reference to the outer class. If your InnerClass is static (one InnerClass for the entire OuterClass class), you'll see that the reference to the outer class is static:
static class InnerClass { ... }
...
//Initialization will become:
OuterClass.InnerClass innerObject = new OuterClass.InnerClass();
^ this part is a static OuterClass reference
On the other hand, in your current scenario (InnerClass is not static), the inner class must be created with a reference to the OuterClass in the form of an object - outerObject. Furthermore, you are actually able to access outerObject from within InnerClass by referring to OuterClass.this:
OuterClass.java
public class OuterClass
{
class InnerClass
{
public OuterClass getOuterClassReference()
{
return OuterClass.this;
}
}
}
Main.java
class Main
{
public static void main(String[] args)
{
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
System.out.println(outerObject);
System.out.println(innerObject.getOuterClassReference());
System.out.println(outerObject == innerObject.getOuterClassReference());
}
}
Output:
OuterClass#36baf30c
OuterClass#36baf30c
true
Here, 36baf30c in the output is an arbitrary memory address. These two output lines will always be the same. As you can clearly see, referring to OuterClass.this from within an InnerClass instance will return the OuterClass instance that was provided at initialization. This is part of the reason that you can't just call new InnerClass() - the reference OuterClass.this cannot be initialized properly without being provided with an instance.
This is the name of the class, and it's likely named this way to make it easier for the compiler to find the definition.
If you declare your variable as just being of type InnerClass, it will look for the file InnerClass.java, but there is no such file.
The dot notation indicates that it's actually a member of OuterClass, so it will look for the definition within the file OuterClass.java.
This is the same thing as using a class from a library,
com.example.MyLibrary.ExternalClass myExternalObject;
JVM does not make a difference between OuterClass and InnerClass: both classes are POJO and separate classes. But InnerClass is not static and therefore it has internal this refers to the instance of OuterClass (therefore it should be created only with existed OuterClass instance)
public class OuterClass {
public class InnerClass {
public OuterClass getOuterClassReference() {
return OuterClass.this;
}
}
}
OuterClass outerObject = new OuterClass();
OuterClass.InnterClass innerObject = outerObject.new InnerClass(); // innerObject has this reference to outerObject
public class OuterClass {
public static class InnerClass {}
}
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = new OuterClass.InnerClass(); // innerObject does not have this reference to outerObject
In other words, you can emulate InnterClass by yourself like this:
public class OuterClass {
}
public class InnerClass {
private final OuterClass outer;
public InnerClass(OuterClass outer) {
this.outer = outer;
}
}
Outerclass.Innerclass is just a part of the Innerclass' full path.
The full path would be something like packagename.Outerclass.Innerclass.
Thus,
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
is really no different from something like:
java.util.ArrayList<T> varName = new java.util.ArrayList<T>();
You can define the inner class as static member of OuterClass
public class OuterClass {
public static class StaticInnerClass {
int i = 0;
public String call() {
i++;
return this.getClass().getName() + " i=" + i;
}
}
}
so defining the static inner class the compile knows that members is a class, the memory area is instanced at compile time (it is accessible in static way) and you can apply the new operator and the new operator instances the class in another memory area.
For example in a main class
public class Main {
public static void main(String[] args) {
/**
* https://stackoverflow.com/questions/57581397/how-instantiating-an-inner-class-in-java-really-works
*
* ### New instance of Inner class
*/
OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
System.out.println(staticInnerClass.call());
System.out.println(staticInnerClass.call());
staticInnerClass = new OuterClass.StaticInnerClass();
System.out.println("\n" + staticInnerClass.call());
System.out.println(staticInnerClass.call());
}
}
with output
// new of inner class and i = 0
innerclass.OuterClass$StaticInnerClass i=1
innerclass.OuterClass$StaticInnerClass i=2
// new of inner class and i = 0
innerclass.OuterClass$StaticInnerClass i=1
innerclass.OuterClass$StaticInnerClass i=2
References: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html.

How outer class is able to access the inner member class directly

When we define inner classes, I understand that static inner classes are accessed with the outer class and inner member class exist with the instance of the outer class.
The confusion is, if I want to hold an instance of an non-private inner member class, then the variable declaration goes like:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
How outer class is able to reference the inner member class like this? What is happening here?
Sample Code:
public class NestedClasses {
public static void main(String[] args) {
A.B b = new A().new B(); // <- How A is directly accessing B, B is not defined as static.
A.StaticClass staticClass = new A.StaticClass();
}
}
class A {
static int x;
int y;
A() {
System.out.println(this.getClass().getName());
}
static class StaticClass {
StaticClass() {
System.out.println(this.getClass().getName());
}
}
class B {
B() {
System.out.println(this.getClass().getName());
}
}
}

why object of inner class cannot be generated in generics

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.

Java: Inner class inside an inner class

Please excuse me if this question has been asked before.
I have searched around the web and here at stack overflow.
Case:
I am stuck at my java project and the compiler won't compile my project when I try to use
an inner class inside another.
Code:
public class outer {
public class middle {
public class inner {
public int variable = "8";
}
}
}
Declaration:
I am trying to declare the classes like this:
outer outerObject = new outer();
outerObject.middle middleObject = outerObject.new middle();
outerObject.middleObject.inner innerObject = outerObject.middleObject.new inner();
Compilation results:
source\start.java:8: error: cannot find symbol
outerObject.middleObject.inner innerObject = outerObject
.middleObject.new inner();
^
Any reply would be much appreciated! Wether my intentions are impossible or if I am simply doing something wrong.
Have a nice day!
The line
outerObject.middleObject.inner innerObject = outerObject.middleObject.new inner();
should be
outer.middle.inner innerObject = middleObject.new inner();
outerObject does not have a middleObject field. Unfortunately Java allows statics to be qualified with variable expressions, so you get some strange code actually compiling.
This would probably be clearer if you stuck with the Java naming conventions.
Your code will never compile as:
public int variable = "8";
This line should be
public int variable = 8;
First change this line.
use this
public class outer {
public class middle {
public class inner {
public int variable = 8;
}
}
public static void main(String[] a) {
outer outerObject = new outer();
middle middleObject = outerObject.new middle();
middle.inner innerObject = middleObject.new inner();
}
}
Please try this :
Outer outerObject = new Outer();
Outer.middle middleObject = outerObject.new middle();
Outer.middle.inner innerObject = middleObject.new inner();
Also you need to change:
public int variable = "8";
to
public String variable = "8";

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