Static inner class vs Companion's inner class - java

Reading chapter 20 of Ordesky's book on Scala, I found that inner classes are path dependant. Among other features, that implies that they can only be instantiated within the outer class or giving an outer class instance.
The question arises: I would like to implement an static inner class in Scala but the author suggest that is not possible.
I immediatelly thought of making the "inner class" (lets call it Inner) a member of Outer's companion object.
The accepted answer of this question seems to point towards that direction.
But that drives to a problem: Inner's type ins't Outer#Inner, I could try something like:
object Outer {
class Inner extends Outer#Inner { }
}
This doesn't work however. Do you know a work arround for this?
I have the hunch that it could be done with abstract types but I am not sure.
Note that making Inner an inner class of the companion objects is not exactly as having a non-path-dependant Inner class because of its type.

I immediatelly thought of making the "inner class" (lets call it Inner) a member of Outer's companion object.
Yes, that's the closest Scala equivalent.
But that drives to a problem: Inner's type ins't Outer#Inner
This isn't a problem, because Outer#Inner is equivalent to a non-static inner class of Outer in Java. I.e. it has a reference to an Outer object.
I would like to get a inner class which is not path dependant or, at least, to know if that is possible
If you want to create a non-companion inner class which can't be used path-dependently, it isn't possible. You are free to always write Outer#Inner instead of o.Inner in your code, of course.

Related

Inheritance and inner classes in java?

I am confused on why should or when shall I write an inner class in java.
Say I encountered a method like execute in some ExecutorService class .parameter of execute is runnable type.Why shall I write inner class for parameter of this method.
Also ,How inheritance work on inner classes like My class has some inner class and how inheritance (i.e. overriding overloading works there).
Pointers\tutorials are welcome.
Thanks in advance
Gaurav
When we use inner classes, we reference their objects with OuterClassName.InnerClassName.
This is necessary because objects of any non-static inner class can only be created in association with an object of the outer class, outside of any non-static method within the outer class.
Take a look at Using inner and nested Java classes for more information and exmples.

Can outer classes call methods of its inner class?

I have code establishing a server connection upon the event that a user clicks a specific button. I created an inner class to listen for the action. Within the single method I have in the inner class, I also establish that server connection mentioned earlier.
My question is, can the Socket connection only be utilized from within the "inner" class? Or, can the outer class proceed with communication with said server?
I do, however, understand that the inner class has unrestricted access to the outer class(as if it were the outer class. My question is the other way around.
Create an instance like this and access what you want:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
All methods declared on the inner class are accessible ... whether they are declared as public or ... private.
If the inner methods are static then they can always be called by code in the outer class. You just need to qualify the method name with the inner class name.
Otherwise, the outer class code needs a reference for an instance of the inner class to call methods on it. (But that's normal.)
(If you were asking about whether an inner class could call methods on the outer class, it is a bit more complicated. Most of the above applies, but if the inner class is NOT static it can also call instance methods on its outer class via this.)
Yes ,you can achieve this look below sample code
currentDateMinutes=getDateAndTime();
System.out.println("DATE & TIME:"+new JobSchedulerUtil().new TaskScheduler(currentDateMinutes).timeNow());
Above code JobSchedulerUtil class is an outer class with having getDateAndTime() method and an inner class TaskScheduler with timeNow() method.

Is it (or not) encouraged to use inner class in Android development?

I read in some book that using inner class will make the app bigger(several KBs per inner class used), but is there any concern about the performance? I saw inner classes used in Google's sample code, but in general, is it encouraged to use inner class or not, in Android?
Thanks!
1. Inner classes are excellent when you want to implement an interface method more than 1 time and in more than 1 way in the same class.
2. Anonymous classes are the best way to create event handlers.
3. Using top level classes (ie static inner class) will be light, as it moreover like an external class which is not having any implicit reference to the outer class.
4. Non-static inner class will be bit of overhead, as it holds implicit reference to the outer class.
Eg:
For inner class having implict reference
Eg:
public class outer{
int x = 10;
class inner{
int x=5;
public void go(){
System.out.println("Inner x: "+ this.x); // Prints x in Inner class
System.out.println("Inner x: "+ Outer.this.x); // Prints x in Outer class
}
}
}
There shouldn't be any significant code size difference between inner classes, anonymous classes, and regular classes. As to the difference between inner and regular, you can unzip your jar and see that a regular .class file is generated for each one.
So don't go nuts with unnecessary ones, but it's also not an "avoid at all costs" scenario either.
As long as you use static inner classes, you'll be fine. Static inner classes are more for arranging classes conveniently and for scoping them properly.
This is not the case with non-static inner classes as they hold a reference to the class that holds them. This is not only heavy, but dangerous too in Android, when the holding class is a live one i.e. has a Context attached to it. This can cause memory leaks, potentially leaking your entire application.
Here is a very similar question (regarding the user of inner classes for adapters in Activities) and the answer:
What is the better way, keeping adapter as an inner class of activity or outside?

Why does Android prefer static classes

I see a lot of java code where android prefers to have developers use static inner classes. Particularly for patterns like the ViewHolder Pattern in custom ListAdapters.
I'm not sure what the differences are between static and non-static classes. I've read about it but it doesn't seem to make sense when concerned with performance or memory-footprint.
It's not just Android developers...
A non-static inner class always keeps an implicit reference to the enclosing object. If you don't need that reference, all it does is cost memory. Consider this:
class Outer {
class NonStaticInner {}
static class StaticInner {}
public List<Object> foo(){
return Arrays.asList(
new NonStaticInner(),
new StaticInner());
}
}
When you compile it, what you get will be something like this:
class Outer {
Outer(){}
public List<Object> foo(){
return Arrays.asList(
new Outer$NonStaticInner(this),
new StaticInner());
}
}
class Outer$NonStaticInner {
private final Outer this$0;
Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; }
}
class Outer$StaticInner {
Outer$StaticInner(){}
}
The main difference between static and non-static inner classes is that a non-static inner class has access to other members of the outer class, even if they are private. Non-static inner classes are a "part" of the outer class. You cannot create nor can they exist without an instance of an outer class. A consequence of this is that an instance of a non-static inner classes are destroyed when the outer class's instance is destroyed.
Static inner classes, on the other hand, are just like normal outer classes. The live and die on their own. You don't need an instance of the outer class for the inner class to exist. That means they also have their own life cycle. They get destroyed when the garbage collector decides to destroy them.
How does this affect memory and/or performance? I really don't know. :)
Static inner classes (i.e. classes declared inside another class with keyword static) are quite similar to "normal" classes except you don't pollute your package's name space. That is their (only) difference and benefit and I believe that's the reason you see it in Android.
Use static inner classes when the purpose of the class is tighten to the main class, but does not depend on its instances. This is generally considered as a good practice.
A non static inner class instance holds a reference to the outer class instance while a static inner class instance does not.
This is relevant for the applications memory footprint as the hidden reference may lead to memory leaks - the garbage collector cannot collect the outer class instance until no more references exist. Also the additional reference itself needs memory, this may be relevant if a high number of instances are used.
class Outer{
class Inner{//Only works with non static inner class
public Outer getOuter(){return Outer.this;}
}
}
It is also relevant for its use, the reference to the outer class is a ctor argument of the inner class, to create a new non static inner class object you have to call the ctor like a memberfunction on an instance of the outer class or from within a memberfunction of the outer class. This means that you cannot have a instance of the inner class without an instance of the outer class.
Outer.Inner in = new Outer().new Inner();
If you decompile an inner class (or watch it using debugger) you can see that there is generated code for accessing the instance of the outer class that was used to create them. The overhead for this is more memory for the additional pointer, more cpu for garbage collection because of additional pointer to test, and if you want to nit pick, longer compile time. Creating instances of non static inner classes is a bit more complicated because you need an instance of the outer class to create them.
Visibility of both static and non-static inner classes can be controlled. Usually they are private if their implementation is strongly connnected to internal details of the outer class, and the developer doesn't think the code can be reused. In this sense they are not better than private functions. Inner classes might be public in cases like Map.Entry, where the inner class is strongly connected to the interface exposed by the class, and the developer doesn't think that Map.Entry can be used without some kind of a Map. Both types have access to private members of the outer class and the outer class has access to private members of the inner class.
Instances of static and non-static inner classes are garbage collected like every other class. There is no special connection between the grabage collection of the outer class and the garbage collection of the inner class.
In the case of UI classes implementation like swing or android you will see static inner classes because they are treated like private function. These classes are not developed for reusability outside the outer class and are strongly connected to the internal implementation of the outer class. There is no reason to expose them and to make sure they can work in more cases than the specific context of the outer class requirements.

How do you resolve a circular dependency with an inner class?

(Java question)
If I reference a field in an inner class, does this cause a circular dependency between the enclosing class and the inner class?
How can I avoid this?
Here is an example:
public class Outer {
private Other o;
private Inner i;
public Outer() {
o = new Other();
i = new Inner() {
public void doSomething() {
o.foo();
}
};
}
}
Static vs instance class: If you declare the inner class as static then the instances of the inner class doesn't have any reference to the outer class. If it's not satic then your inner object efectivelly points to the outer object that created it (it has an implicit reference, in fact, if you use reflection over its constructors you'll see an extra parameter for receiving the outer instance).
Inner instance points outer instance: Circular reference is in case each instance points the other one. A lot of times you use inner classes for elegantly implementing some interface and accessing private fields while not implementing the interface with the outer class. It does mean inner instance points outer instance but doesn't mean the opposite. Not necesary a circular reference.
Closing the circle: Anyway there's nothing wrong with circular referencing in Java. Objects work nicely and when they're not more referenced they're garbage collected. It doesn't matter if they point each other.
The syntax you're using in the example is a little off there is no declaration of the class or interface Inner. But there isn't anything wrong with the concept of the example. In Java it will work fine.
I'm not sure what you're doing here, but you may want to consider a more simple design for maintainability etc.
It's a common pattern for anonymous event handlers to reference elements of their parent class, so no reason to avoid it if that's the case, that's how Java was designed instead of having function pointers.
(Not sure if this is what you are asking...)
At runtime, the inner class has an implicit reference to the instance of the outer class it belongs to. So whenever you pass the inner class instance around, you are also passing the outer class instance around.
You can avoid that by declaring the inner class as "static", but that means that the inner class can't access member variables of the outer class. So in that case if you want to access a member of the outer class, you need to pass it explicitly to the inner class (using a setter or using the constructor of the inner class).

Categories

Resources