Show how scpecific classses like inner, nested, anonymous, enum are compiled. How class file is named etc. Compiled classes must be provided in PR and result should be described in this file.
Nested Classes
Java allows classes and interfaces to be nested within each other. These nested types have unrestricted access
to each other, including to private fields, methods, and constructors. However, from the JVM point of view, access to
the private members of another class is not allowed. To circumvent this limitation, compilers create special access methods.
All of them are static, have access to the package-private and are called starting with access$.
Java 11 brings the notion of nestmates and the associated access rules within the JVM. To achieve this, the class
file format now contains two new attributes:
(NestMembers) to identify the other statically known nest members.
Thus, for types C and D to be nestmates they must have the same nest host. A type C claims to be a member of the
nest hosted by D, if it lists D in its NestHost attribute. The membership is validated if D also lists C in its NestMembers
attribute. Also, type D is implicitly a member of the nest that it hosts. Now there is no need for the compiler to
generate the bridge methods.
Static Nested Classes
As with static members, these belong to their enclosing class, and not to an instance of the class
They can have all types of access modifiers in their declaration. They can define both static and
non-static members.
Accessing Members of the Static Nested Class:
have the same name.
After compilation static nested classes is created Outer$NestedStatic.class where Outer is a name enclosing
class and Inner is a name nested class. In Outer$NestedStatic.class is created constructor with no parameter.
Basically, a static nested class interacts with the instance members of its top-level class, just like any
other classes. So, basically you can and should consider a static nested class as a top-level class which has
been nested inside another top-level class just for packaging convenience.So whenever you are using a nested
class, start by making it static, and then see if you need to access any instance members thereby having an
opportunity to make it non-static.
Inner classes
Just like instance variables and methods, inner classes are associated with an instance of the enclosing class.
They can only define non-static members. They can have all types of access modifiers in their declaration. To
instantiate an inner class, we must first instantiate its enclosing class.
Accessing Members of the Inner Class:
After compilation a classes is generated Outer$Inner.class where Outer is a name enclosing class and Inner is a
name nested class. In Outer$Inner.class is created constructor with takes as a parameter instance of the enclosing class.
Use inner class if you require access to an enclosing instance's non-public fields and methods. Use a static
nested class if you don't require this access.
Local Classes
Local classes are a special type of inner classes – in which the class is defined inside a method or scope block.
They cannot have access modifiers in their declaration. They can only define instance members.
Accessing Members of the Local Class:
After compilation a classes is generated Outer$1InnerLocal.class where Outer is a name enclosing class and InnerLocal is a
name nested class. In Outer$InnerLocal.class is created constructor with takes as a parameter instance of the enclosing class.
Use it if you need to create more than one instance of a class, access its constructor, or introduce a new, named type
Anonymous classes
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.
Accessing Members of the Anonymous Class:
have the same name.
Polymorphism and Anonymous Inner Classes
Because we are using a superclass reference to a subclass object, per the laws of polymorphism,
we can only refer to
- methods defined by the superclass or
- override virtual methods in the subclass
class Anon { }
public class AnonDemo {
public static void main (String[] args) {
Anon anonInner = new Anon() {
public void doSomething() { }
};
anonInner.doSomething(); // Won't compile!
}
}
With a bit of reflection magic, we can achieve a similar effect in Pre-Java 10 code as follows:
anonInner.getClass().getMethod("doSomething").invoke(anonInner);
One of the most visible enhancements in JDK 10 is type inference of local variables with initializers
By using the reserved type name var, Java was able to deduce the exact type of the anonymous inner class.
Consequently, we are no longer stuck with using a superclass reference to access the subclass object.
class Anon { }
public class AnonDemo {
public static void main (String[] args) {
var anonInner = new Anon() {
public void doSomething() { }
};
anonInner.doSomething(); // Work`s!
}
}
After compilation a classes is created Outer$1.class where Outer is a name enclosing class and 1 is a
number anonymous class. In Outer$NestedStatic.class is created constructor with no parameter.
Use it if you need to declare fields or additional methods.
Link in article "How Java 10 Changes the way we Use Anonymous Inner Classes"
Enums
The enum keyword was introduced in Java 5. It denotes a special type of class that always extends the < br />
java.lang.Enum class.Constants defined this way make the code more readable, allow compile-time
checking, document upfront the list of accepted values and avoid unexpected behavior due to invalid
values being passed in. The Enums can be rewritten in Java 8 methods can become so concise with the
use of lambdas and the Stream APIs.
If we compile this code:
public enum Season {
WINTER, SUMMER, SPRING, FALL;
}
and the disassemble with javap MyEnum.class, we'll see this:
public final class Season extends Enum<Season> {
public static final Season WINTER;
public static final Season SUMMER;
public static final Season SPRING;
public static final Season FALL;
private static final Season[] $VALUES;
public static Season[] values();
public static Season valueOf(String);
static {};
}
In values() is a getter for a field $VALUES, which also clones the value before returning it.
That's where our ObjectClone comes from. In static initialiser (the last method) creates this
array as a simple object array, and writing it to the $VALUES field.