I'm having trouble trying to implement this statement I read in Oracle's Docs about Inheritance when it comes to inner classes.
The statement :
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.
In order to test this out i.e. to see if I can achieve the above I created a top level class OC1 which had an inner class IC1 ,then I created another top level class OC2 which extended IC1.
Before I could even start writing a single method , the IDE stopped me at the OC2 class body itself saying
"No enclosing instance of type DataStructure is available due to some intermediate constructor invocation"
I read some other answers and most of them point to either
a) Changing the inner class to static Nested Class -- it resolves the error
b) The whole scenario is unnecessary and convoluted.
Here is the code:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
super();
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
//other methods
//IC1
protected class instanceArr{
private int a = 8;
private static final int B = 4;
protected instanceArr(){
}
protected void doSomething(){
System.out.println("arrayOfInts[] is accessible " + arrayOfInts[6]);
}
}
//main method
}
OC2
public class DataStructureChild extends DataStructure.instanceArr{
public DataStructureChild(){
}
}
I know that the scenario is not an ideal one but I don't want to change inner class to static nested class - it would defeat my purpose of basically trying to see whether arrayOfInts is accessible without OC1's instance in hand.
Am I misinterpreting this statement ? if not then kindly point me in the correct direction.
PS - this is my first question here - apologies in advance if some guidelines were flouted.
Yes, this is a Trap caused by Java's synthetic sugar. You think the inner-non-static-class have the default-no-arguments-constructor but that is wrong. Internally the constructor of IC1 have the OC1 as first argument in the constructor - even if you can not see it.
Thats why the OC2 constructor must use the OC1 as constructor-argument:
public DataStructureChild(DataStructure argument) {
}
Unfortunaltely this is not enougth, you need to get sure the argument is not-null:
public DataStructureChild(DataStructure argument) {
argument.super();
}
It looks very wierd but it works.
You can do this since you inherit access to the inner class of the parent.
class DataStructureChild extends DataStructure {
public DataStructureChild() {
}
public void foo() {
InstanceArr ins = new InstanceArr();
ins.doSomething();
System.out.println(ins.a);
}
}
But could you please give a link or explain where you read the following? 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.
The first part I knew about. But I never considered a separate class extending another classes inner class. Especially since there is usually an implicit relationship between classes and their enclosed inner classes.
Edit:
I believe you misunderstood the statement.
It says that your subclass inherits the inner class. That is true.
It also says that once done you have access to the private values of the inherited inner class. That is also true as demonstrated above:
So it was just talking about access the inner class via inheritance, not extending it directly.
However, if you really want to do have that kind of inheritance relationship without passing references around, you can go this route.
public class Inheritance extends Outer.Inner {
public Inheritance() {
new Outer().super();
}
public static void main(String[] args) {
new Inheritance().start();
}
public void start() {
System.out.println(a);
method();
}
}
class Outer {
public Outer() {
}
protected class Inner {
protected int a = 10;
protected Inner() {
}
protected void method() {
System.out.println("This is a private message");
}
}
}
Related
In below chunk of code, I am creating an anonymous class by extending LinkedList but don't know how can I call-up multiple methods outside the anonymous class. I am able to call one method though as mentioned in end by .dummy1()
void methodOC_3() {
int x = 0;
new LinkedList() {
/**
*
*/
private static final long serialVersionUID = -2091001803840835817L;
// Anonymous class is extending class LinkedList
public void dummy1() {
//x=4; Will give error, Or declare x as final variable
//you can read it As Of Now, since it is effectively final.
System.out.println(x);
}
#SuppressWarnings("unused")
public void dummy2() {
dummy1();
System.out.println("Hey there :) ");
}
}.dummy1();
}
I have just started exploring anonymous classes and inner classes. Please let me know if I am missing anything.
You can't.
The only way to be able to call multiple methods is to assign the anonymous class instance to some variable.
However, in your LinkedList sub-class example you can only assign the anonymous class instance to a LinkedList variable, which will only allow you to call methods of the LinkedList class.
If your anonymous class instance implemented some interface that has dummy1() and dummy2() methods, you could assign that instance to a variable of that interface type, which would allow you to call both dummy1() and dummy2().
Only way to call anonymous class's method is by using reflection with reference variable 'linkedList'
LinkedList linkedList = new LinkedList() { ... }
linkedList.getClass().getMethod("dummy1").invoke();
Why exactly do you want your class anonymous? If it's anonymous, you can't refer to it, and this is exactly your problem. So, just don't make it anonymous! You can define local classes within methods:
public static void methodOC_3() {
int x = 0;
class MyList<X> extends java.util.LinkedList<X> {
/**
*
*/
private static final long serialVersionUID = -2091001803840835817L;
public void dummy1() {
//x=4; Will give error, Or declare x as final variable
//you can read it As Of Now, since it is effectively final.
System.out.println(x);
}
public void dummy2() {
dummy1();
System.out.println("Hey there :) ");
}
}
MyList<String> a = new MyList<String>();
a.dummy1();
a.dummy2();
}
This is very useful especially if you want to define multiple mutually recursive helper methods inside another method, without polluting the name space.
I went searching to learn how to do lambda expressions in Java, but instead a confusion came up for me. So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was. Lot of threads and videos I'm seeing seem to call anonymous inner classes just "anonymous classes." Are they synonymous? My understanding of anonymous inner class is:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
So essentially, instead of having to write a subclass for Square, and then override the calculatePerimeter() method, I can just make a one-time square class, and override the method in their. Is this correct?
So, anonymous inner classes have to do with inheritance. I'm not understanding the use of it though. Perhaps, it's because I've never used them before, or because I don't have much programming experience. Can you can give me examples or explain when it's useful?
UPDATE: When I moved my code for the anonymous inner class to an IDE, I learned that there are errors; So apparently, the "square" doesn't even inherit the fields of the rectangle. Doesn't this make it even more useless?
Would the equivalent be:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
}
public class Square extends Rectangle {
#Override
public void calculatePerimeter() {
perimeter = 4*getLength();
}
public double getLength() {
return length;
}
}
So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
There is no anonymous class there. The class SomeObject has a name ... therefore it is not anonymous. In fact, it is just a normal (non-nested, non-inner, non-anonymous) Java class.
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was.
There is no such thing as a "regular anonymous class". All Java anonymous classes are "inner".
As the JLS says:
"An inner class is a nested class that is not explicitly or implicitly declared static.
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5)."
So, anonymous inner classes have to do with inheritance.
Anonymous inner classes do involve inheritance, but that's not what makes them "inner". See above.
I meant the "list.add(I meant the "list.add(new SomeObject());". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.);". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.
You are incorrect. An object is not a class1.
The new SomeObject() is creating an object, not a class. But that's just normal. Objects / instances don't have names ... as far as the JLS is concerned.
Now variables and fields have names ... but variables are not objects / instances or classes. They are bindings between a name and a slot that can hold a reference to an object (if that's what the type declaration allows).
1 - except in the case of instances of java.lang.Class ... and even then the object is not actually the class / type from a theoretical standpoint.
Or is it called simply an anonymous object and I had two mixed up?
Nope. Objects don't have names. All Java objects are "anonymous". It is not a useful distinction to make. (And see above where I talk about variables ...)
As for your Rectangle / Square examples, they have nothing to do with anonymous classes, inner classes, nested classes or anything like that. They are just top-level classes, using ordinary Java inheritance. (Not that I'm suggesting there is another "non-ordinary" kind of inheritance ...)
First off - square can access fields in Rectangle. You need to mark them protected not private
public class Rectangle {
protected double length;
protected double width;
protected double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
Here are some good descriptions of Inner Classes, Anonymous and local
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html.
There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
Local classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
http://c2.com/cgi/wiki?AnonymousInnerClass
Anonymous Classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
I think the relevance of Anonymous classes comes when you are designing an API. You could create concrete classes to implement every bit of logic for every interface/abstract class but that would create tons of dependencies and you would still be missing some logic. A great example of anonymous classes is when using predicates for filtering. Like in Google Guava
Lets say I have a List<Integer> and I want to filter the numbers remove the 1s and return a new list
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1) rtn.push(i);
}
return rtn;
}
Now lets say I want to filter out 1 and 2
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1 && i != 2) rtn.push(i);
}
return rtn;
}
Now lets say 3 and 5s ... this logic is exactly the same except for the predicate check. So we will create an interface
interface FilterNumber {
public boolean test(Integer i);
}
class Filter1s implements FilterNumber {
public Filter1s(){};
public boolean test(Integer i) { return i != 1; }
}
public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(filterNumber.test(i)) rtn.push(i);
}
return rtn;
}
filter(list, new Filter1s());
As you can see with combinations this becomes tedious too. It would be easier to just allow the user of the api to define the logic they want to preform and if it is only needed once just use an anonymous class
filter(list, new FilterNumber() {
#Override
public boolean test(Integer i) {
return i != 1 && i != 3 && i != 7;
}
});
And extending to Lambdas, wouldn't it be even easier to take out all the bloat around i != 1
list.stream().filter( i -> i != 1 )
To answer a later comment, "when I write a new subclass, it inherits those private instance variables. In the case of the anonymous inner class, it didn't."
Subclasses never "inherit" private fields of the superclass (using the JLS terminology). However, subclasses may be able to refer to those private fields anyway, depending on where they're located. If the subclass is declared inside the superclass, or if they're both nested inside the same top-level class, the methods of the subclass can still access the field; assuming you have a source file C.java with just one class C, private fields declared somewhere in C.java are still accessible from most other places in C.java.
However, when testing this, I found some interesting nuances:
class Foo1 {
private int bar1;
public static class Foo2 extends Foo1 {
public void p() {
System.out.println(bar1); // illegal
System.out.println(((Foo1)this).bar1); // works
}
}
}
bar1 is visible, even though it's a private field in the superclass; it's not inherited, but you can access it by telling the compiler to look at the Foo2 object as a Foo1. But just referring to bar1 by itself fails; Java interprets this as an attempt to get the bar1 of the enclosing instance (not the superclass), but Foo2 is static, so there is no enclosing instance.
Note that if Foo2 were declared outside Foo1, the second println would be illegal, because now bar1 is not visible at all, since it's private. The moral here is that "inheritance" and "visibility" (or "access") aren't the same thing. The same thing applies to anonymous inner classes. If you use one in a place where the private instance field is visible, then you can refer to the field; if you use it in a place where the private instance field is not visible, then you can't. The location of the class declaration is more important than the type of class (nested/inner/anonymous) for this purpose.
Suppose we take away the static keyword and make it an inner class:
public class Foo1 {
private int bar1;
public Foo1(int x) {
bar1 = x;
}
public class Foo2 extends Foo1 {
public Foo2(int x) {
super(x * 10);
}
public void show() {
System.out.println("bar1 = " + bar1);
System.out.println("((Foo1)this).bar1 = " + ((Foo1)this).bar1);
System.out.println("Foo1.this.bar1 = " + Foo1.this.bar1);
}
}
}
public class Test64 {
public static void main(String[] args) {
Foo1 f1 = new Foo1(5);
Foo1.Foo2 f2 = f1.new Foo2(6);
f2.show();
}
}
Now a Foo2 object is also a Foo1; but since it's an inner class, a Foo2 instance also has an enclosing instance that is a different Foo1 object. When we create our Foo2, it users a superclass constructor to set the superclass bar1 to 60. However, it also has an enclosing instance whose bar1 is 5. show() displays this output:
bar1 = 5
((Foo1)this).bar1 = 60
Foo1.this.bar1 = 5
So just bar1 by itself refers to the field in the enclosing instance.
It item no 74 of effective java book there is a paragraph (2nd para from last of the item 74) which mentions as per below:
Inner classes (Item 22) should not implement Serializable. They use
compiler-generated synthetic fields to store references to enclosing
instances and to store values of local variables from enclosing
scopes. How these fields correspond to the class definition is
unspecified, as are the names of anonymous and local classes.
Therefore, the default serialized form of an inner class is ill-
defined.
I know about inner class uses compiler generated synthetic field to store reference to enclosing instances e.g. if the enclosing class is MyEnclosing and inner class is MyInner then the enclosing reference is MyEnclosing.this. But i am not able to get the BOLD part. Please help me getting the meaning. Thanks!!!
Suppose you have a local class like this:
class OuterClass {
Runnable run;
void method() {
final int a = 8;
this.run = new Runnable() {
public void run() {
System.out.println(a);
}
};
}
}
Now suppose I try to serialize this, which contains an object of this inner class type. My compiler names that class OuterClass$1 and gives it a field called val$a. But the exact names to be used in this situation are not part of the compiler's spec. Another compiler might choose to call the inner class OuterClass$method$1. In that case, serializing in one compiled version and deserializing in the other would fail, even though the same source file was used.
(Plus, there's also the problem that an anonymous inner class does not have a no-args constructor. But due to the problem above, even a named inner class cannot reliably serialize)
Consider the following code:
public class Main {
public static void main(String[] args) {
final int x = Integer.valueOf(args[0]);
new Object() {
void print() {
System.out.println(x);
}
}.print();
}
}
My compiler calls the anonymous inner class Main$1. When I disassemble it, I see that a copy of the value of x from the outer scope is stored in a private field called val$x:
private final int val$x;
This is an example of what the bold part is talking about.
An inner class is a non-static class defined within some other class:
class Outer implements Serializable {
private String someString;
class Inner implements Serializable {
private int someInt;
}
}
Once you have an instance of the Inner class, when you serialize it, it must have a reference to the outer class (which it accesses internally via the Outer.this reference) and how this is achieved for a serialized object is unspecified. The same applies to a local class:
class Outer implements Serializable {
private String someString;
Serializable method(final int i) {
class Inner implements Serializable {
Inner() {
System.out.println(i);
}
}
return new Inner();
}
}
If you serialize the value returned by method(), it would need to have a reference to i, but that's not reliable.
I was surprised to see that a private constructor of a nested class is still callable from the nesting class. For example:
public class A{
public void foo(){
//private constructor of B
//can be called from A
B b = new B();
}
//nested class
public static class B{
private B(){
}
}
}
Does this mean that there is no way to enforce the singleton pattern on a nested class? Or am I missing something fundamental here?
It's not just the constructor, any private field or method is accessible:
public class Main {
public static void main(final String[] args) {
final B b = new B();
b.whut();
}
public static class B {
private B() {
System.out.println("hey");
}
private void whut() {
System.out.println("wut?");
}
}
}
Outer classes have access to private fields of their nested classes:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Does this mean that there is no way to enforce the singleton pattern on a nested class?
It depends what you mean by "enforce".
If you mean, can you get the compiler to prevent foo from breaking your 'singleton' invariant - then "No". (Or at least, not unless you make 'B' a non-nested class first ...)
However, the outer class and the nested classes are all defined in the same source file, and should be considered as part of the same unit of abstraction. (And in fact, the fact that A.foo() can call A.B.B means the latter is true in a very real sense.) Therefore, it is the responsibility off A and everything within it to maintain the entire abstraction's invariants ... including singleton-ness of B.
From that perspective, a foo method that breaks the invariant is no different to a hypothetical method on a non-nested "singleton" class that breaks the invariant; e.g.
public Single {
private static Single s = new Single();
public static Single getInstance() { return s; }
private Single() { ... }
public void foo() {
Single ss = new Single(); // breaks the invariant!!
...
}
}
Note the problem ... in both cases ... is that the abstraction is breaking its own invariants.
Does this mean that there is no way to enforce the singleton pattern on a nested class?
It is anyway difficult to implement the singleton (anti) pattern in Java. enums offer a good way, and they work with nesting too:
Does this mean that there is no way to enforce the singleton pattern on a nested class?
enum Outer {
O;
enum Inner { I }
}
If I have class with a nested class, why wouldn't you want it to be static? Is there even a way for two instances of the same class to have different nested classes?
For example:
class MyClass {
public static class myInnerClass {
}
}
why wouldn't you want it to be static
Because I want it to access instance data of a parent object.
Is there even a way for two instances of the same class to have different nested classes?
What do you mean by have? Declared? A class has only one declaration where you list all nested classes. So, in this case the answer is no.
Take for example a Comparator or Runnable (multi-threading) implementations. This is a classic example when you need an extra class that has access to the current instance's fields and methods but is of no use outside of that class. However, static classes could be useful outside the enclosing type, too.
public class EnclosingType
{
private static final class StaticRunnableImplementation implements Runnable
{
private final EnclosingType instance;
public StaticRunnableImplementation(EnclosingType instance)
{
this.instance = instance;
}
#Override
public void run()
{
instance.getSomething();
//getSomething() leads to compile error
}
}
public class NonStaticRunnableImplementation implements Runnable
{
#Override
public void run()
{
doStuff();
}
}
public int getSomething()
{
return 42;
}
public synchronized void doStuff()
{
;
}
public void doSomething()
{
Thread t1 = new Thread(new StaticRunnableImplementation(this));
Thread t2 = new Thread(new NonStaticRunnableImplementation());
t1.start();
t2.start();
}
}
The access to the non-static methods and fields of current instance of the enclosing type, wouldn't be possible if the nested classes would be declared static.
I don't know if I understand your question correctly, but the difference between a static inner class to a non-static is that the second needs a reference from the parent class to be created.
It's preferable to create static class, because of "hidden ciclic references" that can be created. For example, it's normal in GUI developing you do something like
public class View {
private Table table;
...
private void addListeners() {
this.table.addListener(new TableSelectionListener());
}
privte class TableSelectionListener implements Table.SelectionListener {
#Overrides
public void selected(SelectionEvent evt) { /* do stuff.*/ }
}
}
Lots of programmers don't realize, but you now have a circular reference between View and Table, because SelectionListener, being non static, saves a reference to its parent. So
View -> Table -> TableSelectionListener --> View
If you declare TableSelectionListener static it will only need the "namespace" from view to be created, but besides that, it will not save a reference to any View unless you save it on a field. But then, you will return to the first problem :P
Hope that helps :)
A non-static nested class is associated and has access to the members of an enclosing class instance:
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.
If you implement a Listener of some kind, for example, you usually want to call a method on the outer class when you receive the event. In that case, an inner class is simpler than a nested class with an explicit reference to the outer class instance.
That's often used in GUI components. For example (using an API which doesn't actually exist):
public class CircleView extends View {
private final Circle circle = new Circle();
private final Button button = new Button();
public CircleView() {
circle.setColor(Color.RED);
button.addClickListener(new MyClickListener());
}
private toggleColor() {
circle.setColor(circle.getColor() == Color.RED ? Color.BLUE : Color.RED);
}
private class MyClickListener implements ClickListener() {
#Override
public void onClick() {
// Only possible because of the implicit reference:
toggleColor();
}
}
}
A non-static nested class allows the following in an implicit/magical way:
class MyClass {
public static class MyInnerClass {
final MyClass myClass_this;
public MyInnerClass(MyClass parent) {
// Nested class instance has/keeps access to "parent" object.
// In a nested non-static class the "parent" is -guaranteed- to be
// non-null as the nested class can only be created with
// an instance of the containing class.
myClass_this = parent;
}
public Foo bar() {
// Use myClass_this
// Would be available as MyClass.this or implicit resolution in a
// a nested non-static class.
}
}
}
The rules for scope access are also a bit different but the above should show when it might be useful/desirable. In both cases there is only one type for the inner class (MyClass$MyInnerClass), although there can be many instances.
Wether or not this is a "good" thing to have such non-static nested type behavior is debatable, but it is provided in Java.
However, one case where this "non-static" behavior is extremely useful in Java is with anonymous classes (e.g. event handlers or callbacks) which behave as non-static nested classes; while a "different" construct the same mechanism allows accessing methods defined in the enclosing type. Moving the anonymous classes to non-static nested classes can thus merely be viewed as an extension of this common idiom that also allows exposing the nominative type.
(C# has no notion of a "non-static" nested class, but it is easy to emulate it as per above - although I would argue it's usually better to pass a more-refined interface. In addition, other constructs such as closures minimize the need/use even more.)