org.vishia.java2C.test
Class TestAllConcepts

java.lang.Object
  extended by org.vishia.java2C.test.TestAllConcepts

public class TestAllConcepts
extends java.lang.Object

This class contains some examples to demonstrate and test all features of Java2C. The elements all explained respecting the Java2C-features which are tested there.

Most of the methods demonstrates a programming style, which is opportune also in C.
The class is represent in C wit a struct type definition:

 typedef struct TestAllConcepts_Test_t
  { 
    union { ObjectJc object; ImplIfc_Test_s super;} base; 
    int32 simpleInt; 
    ...etc.
  }
  
The first element of struct is a union, which pools the super class, all interfaces and the ObjectJc-base. The most inner super class has ObjectJc as its first Element, the access to that base of all super classes can accessed immediately in this unit.


Field Summary
private  AnyClass anyRef
           
(package private)  SimpleDataStruct[] dataArrayEmbedded
           
(package private)  SimpleDataStruct[] dataArrayRef
           
(package private)  SimpleDataStruct[] dataArraySimpleEmbedded
           
(package private)  SimpleDataStruct[] dataAssociatedEmbeddedArray
          A array of embedded elements, not final.
(package private)  SimpleDataStruct[] dataAssociatedRefArray
           
(package private)  SimpleDataStruct[] dataRefArray
          A array of references, but the head is embedded
(package private)  SimpleDataStruct[] dataRefArrayEmbedded
           
(package private)  SimpleDataStruct embeddedData
          In Java it is a fix build instance at construction time.
(package private)  ExpandedDataStruct embeddedDataExpand
          In Java it is a fix build instance at construction time.
(package private)  SimpleDataStruct embeddedDataNotEnpand
          In Java it is a fix build instance at construction time.
private  ExtendsImpl extendsImpl
           
private  Ifc ifc
          A class reference to an interface, set one time final.
private  Ifc ifc2
          A class reference to an interface, but set only if used.
private  Ifc2 ifc3
           
private  ImplIfc ifc4
          A initialized but not final reference.
private  Ifc ifcNonVirtual
          A class reference to an interface, but it is set to only one instance: Therefore the call of methods at C-level uses the methods of the implemtation, it doesn't use the dynamic call.
private  ImplIfc implifc
          An instance which implements a interface, using to test interface access.
private  ImplIfc implifc2
          A second instance which implements a interface, using to test interface access.
private  int[] intArray
          A initialized array, it is embedded because it's final.
private  int[] intArrayRef
          A initialized array, but it is not embedded because it isn't final.
private  int[] intArrayRef2
          A simple reference to an array.
private  int[] intArrayRefSimple
          A initialized array, but it is not embedded because it isn't final.
private  int[] intArraySimple
          A initialized array, it is embedded because it's final.
(package private) static int[] intArrayStaticConst
           
(package private) static char kCharConst
          A final constant not-int-value, it is a const variable in C.
(package private) static int kIdxMsgOutputFile
           
(package private) static int kMsgBlockHeap
          A total constant value, it is a #define kMsgBlockHeap 9000 in C.
(package private) static int nrofInstances
          A static, but not final variable.
private  int simpleInt
          A simple class variable.
(package private)  java.lang.StringBuffer stringBufferMain
           
private  TestAnonymous testAnonymous
           
(package private)  TestString testString
           
(package private)  TestStringFormatter testStringFormatter
           
(package private)  TestThread testThread
           
(package private)  TestWaitNotify testWaitNotify
           
(package private)  TestWaitNotify.WaitNotifyData testWaitNotifyData
           
 
Constructor Summary
TestAllConcepts()
          The Constructor of this example.
 
Method Summary
 void access(float x)
          A method with same name but other parameter types.
 int access(int x)
           
private  int checkConcatCallReturnAnything()
           
private  int checkConcatCallReturnThisTypefixNonVirtual()
          Deprecated. In this case the calling instance is the same as the returned instance, which is the calling instance for the next concatenated call. In Java it is written:
 a =implifc.returnThisA(34).returnThisA(56).processIfcMethod(44);
 
Because the reference implifc is a embedded instance and the type of it is fix, (the same is for stack instances or @ java2c=instanceType:"Type"-designated references), all method-calls are execute non-dynamic. Because a @ java2c=return-this is designated to the called method, the Java2C-translator accept that the result instance is the same as calling instance, but because that is type-fix, the concatenated call is execute non-dynamic too.
  
 a = 
   ( returnThisA_ImplIfcTest_F(& (ythis->implifc), 34, _thCxt)
   , returnThisA_ImplIfcTest_F(& (ythis->implifc), 56, _thCxt)
   , processIfcMethod_i_ImplIfcTest_F(&((& ((ythis->implifc).base.IfcToTest))->base.object), 44, _thCxt)
   );
 
The instance to call the method is implifc always, it's the first parameter of any called method. That is because the methods are labeled to @ java2c=return-this. The concatenation in Java is presented as a comma-separated expression, see checkConcatenationSimple(). But in this case no temporary references are needed, it is more simple. Lastly the concatenated methods in Java are only a simplifying of writing of the method calls with the same reference.

Note: the expression &((& ((ythis->implifc).base.IfcToTest))->base.object) is needed because the processIfcMethod_i_ImplIfcTest_F is a method of the interface type.
private  int checkConcatenationDynamicCall()
          Example to show concatenated calls of override-able methods.
private  int checkConcatenationDynamicCallToBaseMethods()
          Example to test dynamic and static calls to methods, which are methods of the base class.
private  int checkConcatenationSimple()
          Example to show concatenated calls in a simple variant.
(package private)  void checkNonVirtual()
          Example for a non-dynamic call of an interface referenced method.
private  int checkSomeDynamicCalls()
          This method shows some calls of interface methods, see org.vishia.java2C.Docu.SuperClassesAndInterfaces#callingOverrideableMethods().
 boolean equals(java.lang.Object cmp)
          Check whether Object.equals() will be overridden.
 boolean equals(java.lang.String cmp)
          This method doesn't override Object.equals.
 void finalize()
          Example for a special finalize method body. finalize is called by garbage collection if the object is deleted finally.
private  void main()
           
static void main(java.lang.String[] args)
           
 TestAllConcepts returnThisOverrideable_Test(int value)
          This method helps to test concatenations with return-this, but override-able.
(package private)  int testAccessIfc()
           
(package private)  int testAccessIfcMtbl()
           
(package private)  int testAccessIfcMtbl2(boolean bTest)
           
(package private)  void testInternalDynCall()
          Example to check how an dynamic call of own methods is implemented in C.
 
Methods inherited from class java.lang.Object
clone, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

simpleInt

private int simpleInt
A simple class variable. In C it's a member of the class struct:
 int32 simpleInt;
 
The type int32 is defined in os_types_def.h platform-depending, so that a 32-bit-integer is used.
The initialization with 25 is done in the Constructor, see TestAllConcepts()


kMsgBlockHeap

static final int kMsgBlockHeap
A total constant value, it is a #define kMsgBlockHeap 9000 in C. This is the base of message ident numbers for output Garbage collection activity.

See Also:
Constant Field Values

kIdxMsgOutputFile

static final int kIdxMsgOutputFile
See Also:
Constant Field Values

kCharConst

static final char kCharConst
A final constant not-int-value, it is a const variable in C.

See Also:
Constant Field Values

nrofInstances

static int nrofInstances
A static, but not final variable. It should be intitalized outside the constructor, but in C it is simple implemented like int32 nrofInstances_TestAllConcepts = 5; It may be better, to write in a common initializeStatics()-Method, to regard more complex expressions.


embeddedData

final SimpleDataStruct embeddedData
In Java it is a fix build instance at construction time. In C it is an embedded instance.


embeddedDataNotEnpand

final SimpleDataStruct embeddedDataNotEnpand
In Java it is a fix build instance at construction time. In C it is also an embedded instance. The expandable class isn't expand here because it is final.


embeddedDataExpand

final ExpandedDataStruct embeddedDataExpand
In Java it is a fix build instance at construction time. In C it is also an embedded instance. The expandable class isn't expand here because it is final.


testWaitNotifyData

final TestWaitNotify.WaitNotifyData testWaitNotifyData

testThread

final TestThread testThread

testWaitNotify

final TestWaitNotify testWaitNotify

stringBufferMain

final java.lang.StringBuffer stringBufferMain

testString

final TestString testString

testStringFormatter

final TestStringFormatter testStringFormatter

intArray

private final int[] intArray
A initialized array, it is embedded because it's final.


intArrayRef

private int[] intArrayRef
A initialized array, but it is not embedded because it isn't final.


intArrayRef2

private int[] intArrayRef2
A simple reference to an array. @java2c=noGC.


intArraySimple

private final int[] intArraySimple
A initialized array, it is embedded because it's final. @java2c=simpleArray.


intArrayRefSimple

private int[] intArrayRefSimple
A initialized array, but it is not embedded because it isn't final. @java2c=simpleArray.


intArrayStaticConst

static final int[] intArrayStaticConst

dataArrayRef

SimpleDataStruct[] dataArrayRef

dataArrayEmbedded

final SimpleDataStruct[] dataArrayEmbedded

dataArraySimpleEmbedded

final SimpleDataStruct[] dataArraySimpleEmbedded

dataRefArrayEmbedded

final SimpleDataStruct[] dataRefArrayEmbedded

dataRefArray

final SimpleDataStruct[] dataRefArray
A array of references, but the head is embedded


dataAssociatedEmbeddedArray

SimpleDataStruct[] dataAssociatedEmbeddedArray
A array of embedded elements, not final.


dataAssociatedRefArray

SimpleDataStruct[] dataAssociatedRefArray

implifc

private final ImplIfc implifc
An instance which implements a interface, using to test interface access.


ifc3

private final Ifc2 ifc3

implifc2

private ImplIfc implifc2
A second instance which implements a interface, using to test interface access.


ifc

private final Ifc ifc
A class reference to an interface, set one time final.


ifcNonVirtual

private final Ifc ifcNonVirtual
A class reference to an interface, but it is set to only one instance: Therefore the call of methods at C-level uses the methods of the implemtation, it doesn't use the dynamic call.


ifc2

private Ifc ifc2
A class reference to an interface, but set only if used. It may be referenced to one or another instance depend on fine algorithm.


extendsImpl

private final ExtendsImpl extendsImpl

ifc4

private ImplIfc ifc4
A initialized but not final reference.


anyRef

private final AnyClass anyRef

testAnonymous

private final TestAnonymous testAnonymous
Constructor Detail

TestAllConcepts

public TestAllConcepts()
The Constructor of this example. Before calling the constructor (ctor), the memory space is provided and initialized. The initialization of the memory space contains: This memory initialization is done calling a allocation in the Jc-Runtime environment. If the memory is a static one, the user should call init_ObjectJc(object, sizeof(Instance), ident); manually at C-level. Static instances can be defined at C-level before starting initialization in the C-typical wise.
The constructor starts in C-file with:
 struct TestAllConcepts_Test_t* ctorO_TestAllConcepts_Test(ObjectJc* othis, ThCxt* _thCxt)
 { TestAllConcepts_Test_s* ythis = (TestAllConcepts_Test_s*)othis;  //upcasting to the real class.
   STACKTRC_TENTRY("ctorO_TestAllConcepts_Test");
   checkConsistence_ObjectJc(othis, sizeof(TestAllConcepts_Test_s), null, _thCxt);  
   setReflection_ObjectJc(othis, &reflection_TestAllConcepts_Test_s, sizeof(TestAllConcepts_Test_s));  
 
The next action is the call of constructor of the super class. That constructor calls first the constructor of its superclass and so on. The constructor of Object is not called, because the initialization of memory before executing the constructor initializes the ObjectJc-base. There are contained some informations of memory organization.

Method Detail

access

public int access(int x)

checkSomeDynamicCalls

private int checkSomeDynamicCalls()
This method shows some calls of interface methods, see org.vishia.java2C.Docu.SuperClassesAndInterfaces#callingOverrideableMethods().

Returns:

checkConcatenationSimple

private final int checkConcatenationSimple()
Example to show concatenated calls in a simple variant. Concatenated calls are a well used construct in Java, whereby there are two suggestions to do so:
  1. References are needed, there are got calling a method.

    In C such references are known too, but mostly they are got immediate writing myInstance.ref->refOfRef->variable. It is the adequate construct. The usage of methods instead the immediately getting of the reference is the concept of ObjectOrientation and Encapsulation: The access to the class data should be done always using get-methods. The advantage is: Any access check can be implemented in the get-method. The programming can be implemented more safety. But Lastly it's possible to present a get-method with a primitive macro in C. Than no extra method call is produced, the machine code is the same like the immediately access.

    Sum up: The usage of get-methods instead immediately access to references is recommended.

    This variant of usage is shown in a statement line
       int a = 234 + implifc.returnAnyInstance().returnRef().returnAnyInstance().addValue(24) + 27;
       
  2. calls to the same instance written in a nicely kind, which is associated with a concatenation of data. A typically example in Java is the here shown concatenation of append(...) for a StringBuffer, shown in a second statement line.
       sbufferFix.append("Value=").append(simpleInt).append(" miles");
       
    In comparison with C++, the usage of an C++-expression cout << "Value=" << simpleInt << " miles" phrases the same. The shift operator should phrase a association to "shift in pipe", but at syntactical level it is an concatenation like shown above.

Both application types of concatenation calls should be translated to C in a well readable form. The translated result of both lines is:
    AnyClass_Test_s* _tempRef1; ImplIfcTest_s* _tempRef2; AnyClass_Test_s* _tempRef3; 
    a = 234 + 
      ( _tempRef1= returnAnyInstance_ImplIfcTest(& (ythis->implifc), _thCxt)
      , _tempRef2= returnRef_AnyClass_Test(_tempRef1, _thCxt)
      , _tempRef3= returnAnyInstance_ImplIfcTest(_tempRef2, _thCxt)
      , addValue_AnyClass_Test(_tempRef3, 24, _thCxt)
      ) + 27;

      ( append_s_StringBufferJc(& (ythis->sbufferFix.sb), s0_StringJc("Value="), _thCxt)
      , append_i_StringBufferJc(& (ythis->sbufferFix.sb), ythis->simpleInt, _thCxt)
      , append_s_StringBufferJc(& (ythis->sbufferFix.sb), s0_StringJc(" miles"), _thCxt)
      );
 
In the first concatenation example: The references from each call are parked in temporary variables. That is because the result from the first call is the first parameter of the next call. If temporary variables are not used, the first call may be placed as first parameter of the second call etc. This construct may be lesser able to read, it is a nesting of calls. There is another problem thereby: If method tables are necessary for dynamic calls, the reference is needed twice. Therefore a explicitly temporary reference is proper.

In the second concatenation example: The references are the same in any call because the methods contain
   return this;
 
in its implementation. That is labeled at the methods. The translator knows that therefore and can optimize: All methods use the same reference. The concatenation in Java is translated to a simple order of routine call.

In both examples a comma-separated expression is used. It is a non-often used but possible construct in C. The first examples shows the necessity of that construct: The concatenation is a part of an comprehensive expression, and the calling of the concatenated routines should be done in the correct order. In the second example the comma-separation may be unnecessary, but it's possible and don't may be confusingly. The one-line-expression in Java is broken in several lines at position of the concatenation-representing comma, otherwise the line in C would be to long. This form is better to read.

Returns:
a value.

checkConcatenationDynamicCall

private int checkConcatenationDynamicCall()
Example to show concatenated calls of override-able methods. There are some kinds. The first line in Java
 a = 234 + implifc2.returnAnyInstanceOverrideable().returnRefOverrideable().returnAnyInstanceOverrideable().addValueOverrideable(24) + 27;
 
is related to the first line in checkConcatenationSimple(), but the difference is: all methods are dynamically called. It is a simple non-prepared dynamic call, therefore the code in C may be look catastrophic for real time. The method table of the references have to be got. It is a call of getMtbl_ObjectJc(...) with the given reference as first parameter. But the calculation time is not so expensive, it may be a few nanoseconds if the derivation is not deep, and some more nanoseconds if it is deeper, but not more. Only for hard real-time it is non-opportune. The lines in C are:
    AnyClass_Test_s* _tempRef1; ImplIfcTest_s* _tempRef2; AnyClass_Test_s* _tempRef3; 
    a = 234 + 
      ( _tempRef1= ((Mtbl_ImplIfcTest const*)getMtbl_ObjectJc(&(REFJc(ythis->implifc2))->base.object, sign_Mtbl_ImplIfcTest) )->returnAnyInstanceOverrideable(REFJc(ythis->implifc2), _thCxt)
      , _tempRef2= ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(_tempRef1)->base.object, sign_Mtbl_AnyClass_Test) )->returnRefOverrideable(_tempRef1, _thCxt)
      , _tempRef3= ((Mtbl_ImplIfcTest const*)getMtbl_ObjectJc(&(_tempRef2)->base.object, sign_Mtbl_ImplIfcTest) )->returnAnyInstanceOverrideable(_tempRef2, _thCxt)
      , ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(_tempRef3)->base.object, sign_Mtbl_AnyClass_Test) )->addValueOverrideable(_tempRef3, 24, _thCxt)
      ) + 27;
 
The second line in Java
 a += this.returnThisOverrideable_Test(34).returnThisOverrideable_Test(45).access(56);
 
shows a concatenated call of overrideable methods, which returns this and uses this as first reference. Because this is supported as method-table-reference if it is need, with one access to getMtbl_ObjectJc(...) in the method, and the mthis is used for all calls because the return this-property of the called method is known, this is a optimized access. In C it is:
      Mtbl_TestAllConcepts_Test const* mtthis = (Mtbl_TestAllConcepts_Test const*)getMtbl_ObjectJc(&ythis->base.object, sign_Mtbl_TestAllConcepts_Test);
      ...
      a += 
      ( mtthis->returnThisOverrideable_Test(ythis, 34)
      , mtthis->returnThisOverrideable_Test(ythis, 45)
      , mtthis->access_i(ythis, 56, _thCxt)
      );
 
whereby the first line is generated only one time in the method.

The next line in Java shows a call of dynamic methods of referenced data. The methods returns this, why wet even the reference is the same for all three calls. The reference is copied into a stack variable, which is labeled with @ java2c=dynamic-call. Therefore in C a so named "method-table-reference" is built. This reference contains the pointer to the method table beside the pointer of data. The pointer to the method table is got calling getMtbl_ObjectJc(...) only on setting the reference. It's a part of the macro SETMTBJc(...). So the C-code is optimized. The Java-lines are:
 / **This reference is build in stack because it contains the method-table-reference too: @ java2c=dynamic-call. * /
 AnyClass anyRef2 = anyRef;
 anyRef2.returnThisOverrideable(45).returnThisOverrideable(234).addValueOverrideable(67);
 
The translated C-code is:
    SETMTBJc(anyRef2, REFJc(ythis->anyRef), AnyClass_Test);
    a += 
      ( anyRef2.mtbl->returnThisOverrideable( (anyRef2.ref), 45, _thCxt)
      , anyRef2.mtbl->returnThisOverrideable( (anyRef2.ref), 234, _thCxt)
      , anyRef2.mtbl->addValueOverrideable( (anyRef2.ref), 67, _thCxt)
      );
 
In opposite, if the special stack-local method-table-reference is not built, the C-code isn't optimize, but able to run (translated from next Java line using anyRef as class reference):
    a += 
      ( ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->returnThisOverrideable(REFJc(ythis->anyRef), 345, _thCxt)
      , ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->returnThisOverrideable(REFJc(ythis->anyRef), 3234, _thCxt)
      , ((Mtbl_AnyClass_Test const*)getMtbl_ObjectJc(&(REFJc(ythis->anyRef))->base.object, sign_Mtbl_AnyClass_Test) )->addValueOverrideable(REFJc(ythis->anyRef), 367, _thCxt)
      );
 
shows a call of a dynamic-linked method of a other instance, whereby the return this-property is known too, and the reference is prepared as a locally method-table-reference:

The conclusion:


checkConcatenationDynamicCallToBaseMethods

private int checkConcatenationDynamicCallToBaseMethods()
Example to test dynamic and static calls to methods, which are methods of the base class. The calling of base methods requires the appropriate types of pointers of this.

Returns:

checkConcatCallReturnThisTypefixNonVirtual

private int checkConcatCallReturnThisTypefixNonVirtual()
Deprecated. In this case the calling instance is the same as the returned instance, which is the calling instance for the next concatenated call. In Java it is written:
 a =implifc.returnThisA(34).returnThisA(56).processIfcMethod(44);
 
Because the reference implifc is a embedded instance and the type of it is fix, (the same is for stack instances or @ java2c=instanceType:"Type"-designated references), all method-calls are execute non-dynamic. Because a @ java2c=return-this is designated to the called method, the Java2C-translator accept that the result instance is the same as calling instance, but because that is type-fix, the concatenated call is execute non-dynamic too.
  
 a = 
   ( returnThisA_ImplIfcTest_F(& (ythis->implifc), 34, _thCxt)
   , returnThisA_ImplIfcTest_F(& (ythis->implifc), 56, _thCxt)
   , processIfcMethod_i_ImplIfcTest_F(&((& ((ythis->implifc).base.IfcToTest))->base.object), 44, _thCxt)
   );
 
The instance to call the method is implifc always, it's the first parameter of any called method. That is because the methods are labeled to @ java2c=return-this. The concatenation in Java is presented as a comma-separated expression, see checkConcatenationSimple(). But in this case no temporary references are needed, it is more simple. Lastly the concatenated methods in Java are only a simplifying of writing of the method calls with the same reference.

Note: the expression &((& ((ythis->implifc).base.IfcToTest))->base.object) is needed because the processIfcMethod_i_ImplIfcTest_F is a method of the interface type.

Example to show concatenated calls with the special kind: The methods returns this itself.


checkConcatCallReturnAnything

private int checkConcatCallReturnAnything()

returnThisOverrideable_Test

public TestAllConcepts returnThisOverrideable_Test(int value)
This method helps to test concatenations with return-this, but override-able. The return value is the same as the calling instance. This is recognized by Java2C, if @ java2c=return-this is written.
This is also a example for non-using of STACKTRC, it is not necessary here.

Parameters:
value - any value
Returns:
this

checkNonVirtual

void checkNonVirtual()
Example for a non-dynamic call of an interface referenced method. Because the reference is marked with the instanceType, this information is used to produce a normal C-function call of the known instance method. The additional designation of the reference helps to economize calculation time, if the dynamic call isn't necessary really.
This method is used as an example for using STACKTRC, but without external parameter.


equals

public boolean equals(java.lang.Object cmp)
Check whether Object.equals() will be overridden.

Overrides:
equals in class java.lang.Object
See Also:
Object.equals(java.lang.Object)

equals

public boolean equals(java.lang.String cmp)
This method doesn't override Object.equals.


access

public void access(float x)
A method with same name but other parameter types.

Parameters:
x -

testAccessIfc

int testAccessIfc()

testAccessIfcMtbl

int testAccessIfcMtbl()

testAccessIfcMtbl2

int testAccessIfcMtbl2(boolean bTest)

testInternalDynCall

final void testInternalDynCall()
Example to check how an dynamic call of own methods is implemented in C. The internal non-final method testAccessIfcMtbl() is called twice:


finalize

public void finalize()
Example for a special finalize method body. finalize is called by garbage collection if the object is deleted finally. For Java2C in C all enhanced references will be deleted than. The finalize method is part of override-able methods of Object. The method will be placed in the method table.
The C-code of this method has the following form:
 TODO copy from C
 

Overrides:
finalize in class java.lang.Object

main

private void main()

main

public static void main(java.lang.String[] args)