class Vector extends Object { public$__generic; // A publicfunction add($value){ if(!$value instanceof $this->__generic[0]){// B thrownew IllegalArgumentException('...'); } // ... } }
$v= create('new Vector<lang.types.String>()'); // C
This has the following downsides:
The declaration is quite verbose and introduces a bunch of boilerplate
code for the manual component type verification.
At runtime, two generics, e.g. a vector of strings and one integers,
are "instanceof"-compatible
There is no way to type-hint a generic, verifying a vector's component
type is string would mean manually accessing its __generic member.
Plan
A generic instance should be created at runtime named with unique name
created of the base and component types. A class has two names, one that
is reported by XPClass::getName() (F) and one used literally (L):
// Creates a class named: // F: "util.collections.Vector`1[lang.types.String]" // L: "Vector··String" $ve= create('new Vector<lang.types.String>()');
// Creates a class named: // F: "util.collections.HashTable`2[lang.types.String,lang.Generic]" // L: "HashTable··String¸Generic" $ht= create('new HashTable<lang.types.String, lang.Generic>()');
// Creates a class named: // F: "util.collections.Stack`1[string]" // L: "Stack··þstring" $st= create('new Stack<string>()');
The same generation process happens for all generic interfaces these
classes implement and the generic base classes they extend.
Declaration
To declare a generic class using the XP framework, we will resort to
annotations: