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:

  • One nest member (typically the top-level class) is designated as the nest host. It contains an attribute
    (NestMembers) to identify the other statically known nest members.
  • Each of the other nest members has an attribute (NestHost) to identify its nest host.

    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:

  • they only have access to static members in the enclosing class
  • declaration of a type in an anonymous class shadows any other declarations in the enclosing scope that
    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:

  • has access to all members of the enclosing class, regardless of whether they are static or non-static

    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:

  • has access to both static and non-static members in the enclosing context
  • local inner classes can’t use local variable of outer method until that local variable is not declared as final

    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:

  • has access to the members of its enclosing class
  • cannot access local variables in its enclosing scope that are not declared as final or effectively final.
  • declaration of a type in an anonymous class shadows any other declarations in the enclosing scope that
    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

    1. methods defined by the superclass or
    2. 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.