(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).
Related
My interviewer asked me about inner classes.. After explaining him everything he stopped me on my one sentence- if inner classes can access private members of outer class then doesn't it violate privacy?
I was unable to answer it.
From a JVM perspective, yes, an inner class accessing a private member of the outer class violates privacy.
But, from a Java perspective, no, it does not violate privacy.
JVM perspective
The Java Virtual Machine Specification, section 5.4.4. Access Control says:
A field or method R is accessible to a class or interface D if and only if any of the following is true:
[...]
R is private and is declared in D.
So, the JVM will only allow private members to be accessed from code in the same class, i.e. a nested class cannot access private members of the outer class.
Java perspective
The Java Language Specification, section 6.6.1. Determining Accessibility says:
A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access:
[...]
Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level class (ยง7.6) that encloses the declaration of the member or constructor.
So, a private member in a top-level class and/or nested class is accessible from code anywhere within that top-level class. Since nested classes by definition occur within the body of the enclosing top-level class, code in nested classes can access private members of the outer class.
Synthetic access
To solve the discrepancy, the Java compiler creates hidden (synthetic) methods for allowing "private" access between closely related classes, i.e. between a top-level class and all its nested classes.
This is an internal trick of the compiler and is not really documented in the specifications. JVMS, section 4.7.8. The Synthetic Attribute says:
[...] A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. [...]
The Synthetic attribute was introduced in JDK 1.1 to support nested classes and interfaces.
For more information, do a web search for java synthetic accessor.
See also: Synthetic accessor method warning
Answer is No as inner class is part of the outer class, just like other variable and methods are
All private variable/method of a class can be accessed inside all methods of the same class. An inner class is a special case where an instance of InnerClass can exist only within an instance of OuterClass. Hence it has direct access to the methods and fields of its enclosing instance.
The answer is NO, because inner class has internal link to the outer class and inner class does not exists without concrecte instance of outer class.
But if you add static to the inner class declaration, it means the it does not have link to the outer class and this is the same, when you declare class in it's own file.
That is all, clear and simple.
If you look closely at statement#1 and #2, you will find that the only difference between them is of one extra object (of inner class) that gets created in #1, rest everything access-wise is exactly same.
There is no violation because somewhere you're intentionally leaving the door open through some form of access specifier like public or protected. Inner class doesn't act (or is not capable to act) as a workaround in there, so no violation absolutely.
public class AccessPrivateMemberThruInnerClass {
private int getUniqueId() {
return 101;
}
private class AnInnerClass {
public int getParentID() {
return getUniqueId(); // invokes private method inside a public method.
}
}
public int getUniqueIdForce() {
return getUniqueId(); // invokes private method inside a public method.
}
public AnInnerClass getInnerClassObject(){
return new AnInnerClass();
}
public static void main(String[] args) {
AccessPrivateMemberThruInnerClass obj = new AccessPrivateMemberThruInnerClass();
System.out.println(obj.getInnerClassObject().getParentID()); // #1
System.out.println(obj.getUniqueIdForce()); // #2
}
}
Answer : No inner class does not voilate the privacy of outer class.
Explanation : All instance methods defined in a class are able to access the private or not private fields and methods defined in the class. This happens as all the instance methods and fields belong to the current object of the class.
Same is true for any inner (non static) class, it has an implicit reference of outerclass current object.
This is the reason as why you can only create the object of inner (non static) class with the help of an object of outer class. If you create the object of inner class inside any instance method of outer class then it is created with the help of implicit current object reference of the outer class.
If you have inner class which is static, then it does not has implicit reference to current object of outer class. Any instance field or method belong to an Object of the class. Hence static inner class can not access any private or non private instance field or method of outer class.
You can set reference of outer container class object explicitly and then it can acess. Now with the help of this explicitly set reference of outer class you can access the private Fields and methods.
So now lets modify the question as why inner static class with an explicit reference of outer class can acess and modify private methods and fields ?
Answer is related to our decision for having such design. The intention of defining any entity within the scope of a class is belongingness. If belongingness is missing then you should reconsider your decision lf making the class as inner (static or non static). Inner classes should be made when we wish to encapsulate a sub responsibility to an entity. This makes the related responsibility still cohesive.
Iterator is a part of any Collection and hence it is inner class. Custom AsyncTask class defined in custom Activity class in android is often made as private static (with weak reference of outer class activity) to prevwnt activity leak as the intention is to modify the fields which are private.
P.S : Afer compiler compiles the code it generates separate files for inner class and you can refer the link to understand as how the interaction of fields of one class being accessible to other class happens when other class is defined as inner class
https://stackoverflow.com/a/24312109/504133 . Actually synthetic getters and setters are injected in the code by compiler so as nested static class can access private fields using these. But still this is backend task done by langauge tools.
I wrote a class following the Singleton-pattern and would like to write a inner class for it next.
What worries me is that the inner class is able to access all of the outer classes private fields, including the private field for the single instance and i suppose the private constructor likewise.
Is it possible to attack the singleton and to make a second instance of it when one has access to the constructor of the inner class?
I was thinking of some kind of navigating from an instance of the inner class to the constructor of the class.
So for example:
class Outer{
private static Outer instance;
private Outer(){}
public static Outer getInstance(){
if(instance==null)instance= new Outer();
return instance;
}
class Inner{
public Inner(){}
}
and now something like:
public class Main{
public static void main(String[]args){
Outer outer = Outer.getInstance();
Inner inner = outer.new Inner();
Outer outer2 = inner.Outer.this.new Outer();
}
}
Noticing that the last line is not compilable I thought there might be some other way to "navigate" to the constructor of the outer class once one has an object of the inner class.
What worries me is that the inner class is able to access all of the
outer classes private fields, including the private field for the
single instance and i suppose the private constructor likewise.
That's the whole purpose in life of inner class, read more here, inner classes are meant for the situation when you want to keep some state of a class as private but still want a cohesive class to access it, so in those situation you make an inner class for that top level class.
Is it possible to attack the singleton and to make a second instance
of it when one has access to the constructor of the inner class?
If you have implemented proper singleton pattern for your top level class then no-one can create another instance of your top level class.
Also, just in case if you are thinking otherwise then when you create an instance of inner class then it doesn't create an instance of outer class, no there again there are scenarios like if you have a static inner class then you do need an instance of top level class but if you have a non-static inner class then first you need to create a instance of top level class and then you create instance of your inner class, but whole point is that creating an instance of inner class doesn't create another instance of outer class, so if you have implemented singleton pattern properly in our outer class then you are fine.
I would recommend you to read about inner classes here.
Singleton-pattern destroyable by inner class?
With above explanation, answer is no, with a properly implemented singleton pattern in top level class, an inner of it cannot create another instance of the top level class.
Your question seems to indicate that you're trying to prevent an attacker from making specific changes in your source code. If someone has that level of access already, there's no security on Earth that can protect you from an attack.
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.
I came across something like
ArgProcessor argProcessor = runWebApp.new ArgProcessor(options);
This line is from the source of GWT. By digging into Java's grammar I found it to be (".new") inner creator.
But I didn't find any proper documentation about why exactly we need the inner creator.
How does this differ from a normal object/instance creator?
It is for creating an object of the inner class type.
for example: look at this
http://www.javabeat.net/tips/124-inner-classes-in-java.html
ie:
class Outer{
final int z=10;
class Inner extends HasStatic {
static final int x = 3;
static int y = 4;
}
public static void main(String[] args) {
Outer outer=new Outer();
System.out.println(outer.new Inner().y);
}
}
The new keyword in this example is called within the scope of the runWebApp instance. This means that runWebApp.class contains an inner class called ArgProcessor. This is the appropriate way to specify you are construction ArgProcessor within runWebApp, and not calling some other top level ArgProcessor class.
Note that the external assignment will have an instance of ArgProcessor, but it will be runWebApp's instance of ArgProcessor, and not some other instance's ArgProcessor instance. Occasionally, this is done to simulate an old style C++ friend interface between classes; however, there are other reasons why this might be done. It basically allows a more fine grained approach than the standard public, protected, default, private interfaces available with the actual programming language.
An inner class is a class defined in another class. If it is not static, each instance of an inner class has an implicit reference to the instance of the outer class. It can be accessed from within the inner class like this: OuterClass.this.
So, when you instantiate the inner class InnerClass from a non static method of the instance outerObject of the outer class OuterClass, the created instance innerObject has an implicit reference to outerObject. But when you want to do the same from somewhere outside of OuterClass (or from a static method), you have to specify the instance of OuterClass it will reference: you do that by calling new on the instance of the outer class.
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.