I know that Anonymous class does'nt have any name.
It is used inside the Simple classes.But more than this,how Anonymous classes are different from Simple classes we use?
Anonymous classes are the same as local classes except they don't have a name.
They are expressions not declarations. So it will be part of a staement (i.e. the statement which creates the object and so we are placing a semicolumn after an anonymous class definition). You can use an anonymous class if you need to use it only once.
Major points:
You cannot declare a constructor inside it.
Can access all class level variables of the enclosing class and only final local variables.
Cannot declare static initializers, but can have static variables which are declared as final also.
In Java 8 lambdas are having similar syntax to anonymous classes and they can replace anonymous classes if you need a stateless implementation.
They are mostly used in UI programs to handle events. If your class/interface does a little functionality then instead of creating new file for it you embed it in the existing class. You can find elaborate description on https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html.
Related
I have a Java class that is about 4,000 lines long (lots of methods). This class then uses about 200 small classes that only it needs, so another 4,000 lines of code.
If this was C# I would put those other in a partial class file so different file, but they would remain private nested classes only visible to the parent class.
Is there a way to do this in Java? I'm not asking for some methods to be in a distinct file, but for private nested classes to be in a distinct file.
thanks - dave
You can't make a class private to only another class while putting it in a different file.
Use no class access modifier
What you can do is put the classes in separate files with no access modifiers (omit "public"), which will make them package-private, i.e. visible only within its own package. See also the official Access Control tutorial.
UtilClasses.java:
package OurPackage;
class UtilClass1
{
}
class UtilClass2
{
}
MainClass.java:
package OurPackage;
public class MainClass
{
UtilClass1 iAmAUtilClass;
}
Use interfaces or inheritance
You can also achieve something similar with either interfaces or inheritance, by omitting the access modifier from the nested class. This would also be package-private, but this might be preferable to the above in some circumstances, since it avoids having all the nested classes at the top level.
BaseInterface.java:
package OurPackage;
interface BaseInterface
{
class UtilClass1
{
}
}
MainClass.java:
package OurPackage;
public class MainClass implements BaseInterface
{
UtilClass1 iAmAUtilClass;
}
You can also use a base class instead of an interface and extend that with roughly the same effect.
You don't need to implement BaseInterface gain access to its nested classes, but, if you don't, you'd need to use BaseClass.UtilClass1 instead of just UtilClass1.
Inner private classes can't be "extracted" and still be visible only to one particular class. One solution is already mentioned in the comments: Create a package that contains the "main" class and all the previously inner classes and make the inner classes package visible. This would also allow you to create unit tests testing for the correct functionalities of the inner classes, which is something that is most likely currently not happening simply because the inner classes can't be "reached" by a unit test at the moment.
Concepts like declaring "friendships" between classes like in C++ don't exist in Java.
You can replace the inner classes with top-level ones, but you'll have to rewrite a lot of things by hand that the compiler auto-wires for you with the inner-class relationship. To the Virtual Machine, an inner class is nothing special, it's just another class in the same package as the outer class with a fancy name. But the compiler creates a lot of helper constructs under the hood, that you have to reconstruct by hand (or have some refactoring tool do that for you):
The inner class can refer to the outer this instance, by prefixing it with the outer class name. You need to pass the outer this into your inner constructor and store it in a field like outerThis to get access.
In the source code, you can call the outer-class methods directly. You need to rewrite it like outerThis.method(). The same applies to fields.
For private outer methods and fields to become accessible, the compiler creates bridge constructs for you. You have to either change access modifiers or create package-private bridge methods yourself.
In the end, you'll have the former inner classes at least package-visible and being more verbose than the original ones, but on the other hand you'll get better isolation and testability.
This question already has answers here:
Why are only final variables accessible in anonymous class?
(15 answers)
Cannot refer to a non-final variable inside an inner class defined in a different method
(20 answers)
Closed 7 years ago.
final JTextField jtfContent = new JTextField();
btnOK.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent event){
jtfContent.setText("I am OK");
}
} );
If I omit final, I see the error "Cannot refer to a non-final variable jtfContent inside an inner class defined in a different method".
Why must an anonymous inner class require the outer classes instance variable to be final in order to access it?
Well first, let's all relax, and please put that gun down.
OK. Now the reason the language insists on that is that it cheats in order to provide your inner class functions access to the local variables they crave. The runtime makes a copy of the local execution context (and etc. as appropriate), and thus it insists that you make everything final so it can keep things honest.
If it didn't do that, then code that changed the value of a local variable after your object was constructed but before the inner class function runs might be confusing and weird.
This is the essence of a lot of the brouhaha around Java and "closures".
Note: the opening paragraph was a joke in reference to some all-caps text in the original composition of the OP.
The methods in an anonymous class
don't really have access to local
variables and method parameters.
Rather, when an object of the
anonymous class is instantiated,
copies of the final local
variables and method parameters
referred to by the object's methods
are stored as instance variables in
the object. The methods in the object
of the anonymous class really access
those hidden instance variables. [1]
Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.
[1] http://www.developer.com/java/other/article.php/3300881/The-Essence-of-OOP-using-Java-Anonymous-Classes.htm
The variables around the definition of the class live on the stack, so they are probably gone when the code inside the inner class runs (if you want to know why, search stack and heap). That's why inner classes don't actually use the variables in the containing method, but are constructed with copies of them.
This means that if you change the variable in the containing method after constructing the inner class, its value won't change in the inner class, even though you'd expect it to. To prevent confusion there, Java requires them to be final, so you expect not to be able to modify them.
The reason is that Java do not fully support so-called "Closures" - in which case the final would not be necessary - but instead have found a trick by letting the compiler generate some hidden variables which is used to give the functionality you see.
If you disassemble the generated byte code you can see how the compiler does it, including the strangely named hidden variables containing copies of the final variables.
It is an elegant solution to give functionality without bending the language backwards to do so.
Edit: For Java 8 lambdas give a more concise way to do what was previously done with anonymous classes. The restrictions on variables have also loosened from "final" to "essentially final" - you do not have to declare it final, but if it is treated like it is final (you could add the final keyword and your code would still compile) it can be used. This is a really nice change.
Since Java 8 final modifier is optional for outer instance variables. Value should be 'effectively final'. See answer Difference between final and effectively final.
I have been facing so many problem using the anonymous class like I can't perform the instanceOf test neither can I implements multiple interface, so could someone please explain what I can or can not do with the anonymous class in java ?
The purpose of an anonymous inner class is to extend and instantiate an existing class or implement a single interface in one step.
Its limitations can be derived from the above:
Only one non-final class can be extended or one interface implemented.
Only final local variables of the enclosing method can be accessed. (This is due to the fact that normal local variables will be out of scope by the time any methods of the inner class will be invoked.)
You can't define a constructor. (The class has no name.)
If you need multiple interfaces, you can use a local inner class, which is like a normal inner class, with its own name, but defined within a method. I have to admit I've never seen it used in practice and I see very little reason for anyone to do so, hopefully someone will come up with an example.
Anonymous classes work whenever
you never need to refer to the class itself
you only need to extend a single class or implement a single interface
...but other than that there aren't really any significant constraints. This works fine in a lot of cases: for example, many cases when you're defining callbacks, listeners, or the like.
This question already has answers here:
Why are only final variables accessible in anonymous class?
(15 answers)
Cannot refer to a non-final variable inside an inner class defined in a different method
(20 answers)
Closed 7 years ago.
final JTextField jtfContent = new JTextField();
btnOK.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent event){
jtfContent.setText("I am OK");
}
} );
If I omit final, I see the error "Cannot refer to a non-final variable jtfContent inside an inner class defined in a different method".
Why must an anonymous inner class require the outer classes instance variable to be final in order to access it?
Well first, let's all relax, and please put that gun down.
OK. Now the reason the language insists on that is that it cheats in order to provide your inner class functions access to the local variables they crave. The runtime makes a copy of the local execution context (and etc. as appropriate), and thus it insists that you make everything final so it can keep things honest.
If it didn't do that, then code that changed the value of a local variable after your object was constructed but before the inner class function runs might be confusing and weird.
This is the essence of a lot of the brouhaha around Java and "closures".
Note: the opening paragraph was a joke in reference to some all-caps text in the original composition of the OP.
The methods in an anonymous class
don't really have access to local
variables and method parameters.
Rather, when an object of the
anonymous class is instantiated,
copies of the final local
variables and method parameters
referred to by the object's methods
are stored as instance variables in
the object. The methods in the object
of the anonymous class really access
those hidden instance variables. [1]
Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.
[1] http://www.developer.com/java/other/article.php/3300881/The-Essence-of-OOP-using-Java-Anonymous-Classes.htm
The variables around the definition of the class live on the stack, so they are probably gone when the code inside the inner class runs (if you want to know why, search stack and heap). That's why inner classes don't actually use the variables in the containing method, but are constructed with copies of them.
This means that if you change the variable in the containing method after constructing the inner class, its value won't change in the inner class, even though you'd expect it to. To prevent confusion there, Java requires them to be final, so you expect not to be able to modify them.
The reason is that Java do not fully support so-called "Closures" - in which case the final would not be necessary - but instead have found a trick by letting the compiler generate some hidden variables which is used to give the functionality you see.
If you disassemble the generated byte code you can see how the compiler does it, including the strangely named hidden variables containing copies of the final variables.
It is an elegant solution to give functionality without bending the language backwards to do so.
Edit: For Java 8 lambdas give a more concise way to do what was previously done with anonymous classes. The restrictions on variables have also loosened from "final" to "essentially final" - you do not have to declare it final, but if it is treated like it is final (you could add the final keyword and your code would still compile) it can be used. This is a really nice change.
Since Java 8 final modifier is optional for outer instance variables. Value should be 'effectively final'. See answer Difference between final and effectively final.
I have an anonymous inner class inside another class (SomeClass).
Both SomeClass.class.getClasses() and SomeClass.class.getDeclaredClasses() return empty arrays.
I couldn't find some hints on this in Class' Javadocs.
Can anonymous inner classes be retrieved using reflection in some way?
What else are notable differences between anonymous inner classes and normal inner classes?
You could try a brute force search of Class$1 ... Class$n until you can't find any more.
If it's using reflection, it's probably a really bad idea. Leaving that aside, I believe you can additional inner classes at runtime, so it doesn't make sense to list classes that may not have been thought of yet. Listing currently loaded classes would, I guess, require going through Java agents or similar.
Anonymous inner classes have made up names, an enclosing method and additional synthetic fields for copying external local variables that have been copied. One class is pretty much the same as another at runtime. Remember that 1.1 introduced inner classes, but class files have barely changed since 1.0.