public class Docu.E_Inner_classes extends java.lang.Object
final RefType name = new BaseType(param){ //classBody of enhancing. };That classes are able to use in coherence with that variable only. Nevertheless there are not binded to the variable, the variable holds the reference only. It is possible to assign the reference to another element. The class exists independently as definition and code snippet but is is access-able via the base-typed-reference only. The variable-initialization may be final or not. The final usage is typical though the final keyword is missed in Java-sources often.
outer
-reference.
final static RefType name = new BaseType(param){ //classBody of enhancing. };Its usage with the variable are equivalent with non-static-inner classed, but the variable is static and inside that class only static elements can be used.
methodCall(parameter, new BaseType(param){ ...body }, ...)or
(new BaseType(param){ ...body }).executeMethod();In any case an instance is built with that type. The instance is referenced as is the rule. The reference can be assigned inside the called method. In the second example the reference may be stored in the
executeMethod()
because it is given
as this
there. The class is access-able with that reference only.
Constructor and Description |
---|
Docu.E_Inner_classes() |
Modifier and Type | Method and Description |
---|---|
void |
e1_anonymousClasses()
Anonymous classes are a special construct of Java.
|
void |
fieldIdentsOfOuterClassAndSiblings()
The knowledge of field-identifiers and types of the outer classes and the sibling- inner classes
in inner classes and the knowledge of this one of the super classes in the derived classes
is necessary.
|
void |
firstPassOfInnerClasses()
The first pass of the inner classes are running while the first pass of the enclosing class
is processed.
|
void |
typeIdentsOfOuterClassAndSiblings()
The types of the outer class are registered for the inner class running
ClassData.completeTypesForInnerClasses() at the end of the first stage of the
first pass of the outer class. |
public Docu.E_Inner_classes()
public void e1_anonymousClasses()
static RefType name = new BaseType(param){ //classBody of enhancing. };The
RefType
may be a super- or interface-Type of BaseType
or typical the same as BaseType
. With this type the anoymous class is used.
BaseType
is the direct super type of the defined instance.
classBody for enhancing
may be overwrite some methods
of the BaseType
and can contain some variables or inner classes etc. too,
all what a class can be have. But it isn't possible to access other than the methods,
which are overridden. Only the overridden methods are visible in the RefType
.
BaseType
.
The classBody for enhancing
may define variable which can be initialized,
but an extra constructor is not possible to write.
classBody for enhancing
can access especially all elements
from the outer class, if this class is non-static, without the shown static-keyword.
Then a portal for example from an interface to the outer class through the anonymous class
is given. This is the most interisting aspect of inner anonymous classes. They implements
methods of the interface or overrides methods, but the methods are seperated from the outer class.
Not the outer class plays the role of the interface-implementer, but only the anonymous class.
That makes the implementing better supervise-able, respectively it allows the usage
of method names, which may be in coflicting with other interface implementations.
Therefore it is an important concept for programming.
new Type(param){ }
.
The suggestion, the declared variable is related immediate to the anonymous class is false.
The variable is only the reference to the instance of the anonymous class.
A creation of an anonymous class-instance can also be done as part of an expression.
If the anonymous class is defined inside a statement block, it is equal to definition it
as normal inner class at class level. It means the variables of the outer class body
can be accessed, but not the variables of the enclosing statement block.
GenerateClass#createFieldDataNewObject(org.vishia.zbnf.ZbnfParseResultItem, org.vishia.zbnf.ZbnfParseResultItem, LocalIdents, LocalIdents, StatementBlock, String, ClassData, char, char, char, boolean)
There the method GenerateClass#gen_AnonymousClass(org.vishia.zbnf.ZbnfParseResultItem, org.vishia.zbnf.ZbnfParseResultItem, LocalIdents, StatementBlock, String, char, GenerateFile)
is called. Inside that, the FirstPass#runFirstPassClass(GenerateFile, String, String, String, String, org.vishia.zbnf.ZbnfParseResultItem, String, ClassData, java.util.List, boolean, ClassData)
is called with an own instance of FirstPass
and the ClassData
of the anonymous type are produced.
iWriteContent.writeCdefs(StringBuilder)
-method,
which writes to GenerateFile.uFileCDefinitions
buffer. This is placed before the
adequate GenerateFile.uFileCSecondPath
for the bodies. The definition of anonymous classes
in bodies of methods are never direct access-able outside, only via its base classes.
So it shouldn't be defined in Headerfiles. But they are able to reference from outside.
Therefore, the reflection information is able to use unconditionally.
{ //inside method body struct { data x; } stackVariable;which may be usual in C, it is not used in Java2C-translated codes.The machine code effort is not lesser which such an construct against the extra definition of the struct with a internal-build-name und use it with its name. But the representation of a extra definition is better. It is necessary for reflection and others. The anonymous class in Java has more capability as the anonymous struct in C like shown above.
BaseType
, selected by the actual parameters. It is overridden,
because the own local variables should be intialized too.
C_
NameOfVariableSuffixOuterClass
for all anonymous classes of variable initialization. if a new(..){...} outside of an variable
is translated, then C
Nr_
NameOfMethodSuffixOuterClass
is used to build the name, where Nr is the current number of anonymous class in the method,
started with 1 and mostly 1. This names mustn't be used as class-names by the user for other elements.
But there are specialized so that isn't suggest to do so.public void firstPassOfInnerClasses()
ClassData
of the
inner classes may necessary to know, the ClassData are created as result of running its
first pass.
public void fieldIdentsOfOuterClassAndSiblings()
FieldData.nClassLevel
and FieldData.nOuterLevel
. See Docu.E_Inner_classes
The field-identifier of the outer class are registered for the inner class running
ClassData.completeFieldIdentsForInnerClasses()
at the end of the first pass.
That is necessary because all idents are known only at the end of the first pass of the
outer class, but the first pass of the inner class is finished already, without knowledge
of the outer idents. All idents should be known while running the second pass only.
ClassData#completeFieldIdentsFromOuterClass(LocalIdents)
is called unlike
if a class is generated in the second pass inside a block statement. In this case the
first pass of this class is running only in the second pass of the environment.
public void typeIdentsOfOuterClassAndSiblings()
ClassData.completeTypesForInnerClasses()
at the end of the first stage of the
first pass of the outer class. This is done after calling FirstPass#buildType(StringBuilder, String, GenerateFile, String, String, String, String, org.vishia.zbnf.ZbnfParseResultItem, boolean, String, ClassData, java.util.List, boolean, ClassData, char)
in the GenerateFile#runFirstPassFile(org.vishia.zbnf.ZbnfParseResultItem, String, String, String)
-routine respectively in ReadStructure.postPrepare(org.vishia.java2C.ReadStructure.ZbnfToplevel)
for creation of ClassData from the stc-file.
That is necessary because all types are known only at the end of the first stage
of the first pass of the
outer class, but the first passes of the inner classes are finished already, without knowledge
of the outer idents. All idents should be known while running the second stage of first pass
(FirstPass.runFirstPass2(StringBuilder)
) and the second pass only.
FirstPass#gatherAllDefinitions(GenerateFile)
) run before runFirstPass2. It means there are 3 stages, because generation of methods inline or as macro.
GenerateClass#gen_AnonymousClass(org.vishia.zbnf.ZbnfParseResultItem, org.vishia.zbnf.ZbnfParseResultItem, LocalIdents, StatementBlock, String, char, GenerateFile)
-routine after processing the FirstPass#buildType(StringBuilder, String, GenerateFile, String, String, String, String, org.vishia.zbnf.ZbnfParseResultItem, boolean, String, ClassData, java.util.List, boolean, ClassData, char)
of the anonymous class. In that time all types are known already, because the first stage
of the outer class is running already and all types except the anonymous are known.
ClassData
of the anonymous classes shouldn't be known as types, because there are
anonymous. It pertains to all class-level anonymous class and statement-block anonymous classes.
ClassData
of statement-block-level classes shouldn't be known as types,
because there are visible only at that statement-block level.