Wednesday Mar 07, 2007
Wednesday Mar 07, 2007
Generics was a new feature in Java 5. This is not new, because Java 5 has been out for a long time now. Now that NetBeans has UML support, we are getting a lot of questions about UML support of Generics. I will make an attempt to demonstrate how UML can represent generics.
In UML every classifier can have template parameters. Classifiers are things like Class, Interfaces, and even Use Cases. To use a template you have to create an instance of the template. The instance of a template is a new type. Creating an instance of a template is similar to extending a class. This is not to far fetched, because when templates was first added to C++, many C++ compiler would actually create a new class declaration for every new template instantiation. Then compile the new template decloration. So, ArrayList < String > is a completely different type than ArrayList < Integer >, and vise versa. You can not assign a ArrayList < Integer > a variable that is declared to be of a ArrayList < String >. UML has the same concepts. UML actually has two different mechanism to represent generic instances.
The first is called an anonymous classifier (In the NetBeans UML module, we use the term Derivation Classifier). The anonymous classifier is used to define an instance of a template. The anonymous class uses syntax to declare the template name, and the arguments being passed into the template. The NetBeans UML currently does not use the UML notation, but instead uses a more Java like notation.
The second approach is to use a derivation edge. You can draw a derivation edge between a classifier and a template. A derivation edge has bindings that are used to specify the template arguments. The anonymous classifier is simply a shortcut, for the derivation classifier approach. A problem with the derivation edge approach is that you there is no way to determine that a derivation is for generalizing from a class, or implementing an interface. Code generation can try to determine if a derivation is for implementation or generalization, if Classes and interfaces are used. However, if you start to use constructs like DataTypes to represent classifiers declared in a library things get are not so clear. Also, when you are generalizations, and implementation links, the picture get cloudy when you start to use a third relationship to represent a super class relationships (not to mention that the derivation edge looks like an implementation link with bindings). For these reasons the NetBeans UML module does not currently allow derivation edges to be drawn from a class to a template. In the future when we have better support for libraries, we will probably add this feature into the tool.
Following are a few examples of how the Java generics are represented in UML.
Example 1
The follow class declaration declares a class that extends a generic type. The the super type is a generic instance of MyGeneric, with the argument of String.
public class MyExtendedGeneric extends MyGeneric < String >
{
}
The NetBeans UML reverse engineering module will create a class that extends a derivation classifier. The derivation classifier will have a derivation to the MyGeneric template, and its binding will specify that argument is a String.
Example 2
The follow class declaration declares a class that implements a generic type. The the super interface is a generic instance of MyGenericInterface, with the argument of String.
public class MyExtendedGeneric implements MyGenericInterface < String >
{
}
The NetBeans UML reverse engineering module will create a class that implements a derivation classifier. The derivation classifier will have a derivation to the MyGenericInterface template, and its binding will specify that argument is a String. For the use case the NetBeans UML module has actually extended UML. In standard UML, an implementation link can only be created between a classifier and an interface. However, in order to better support templates NetBeans allows an implementation to be created between classifiers and derivation classifiers as well.
Example 3
The follow class declaration declares a class that has one data member. The type of the data member is an instance of the generic MyGeneric, with the argument of String.
public class MyClass
{
MyGeneric < String > myAttr = new MyGeneric < String >();
}
The NetBeans UML reverse engineering module will create a class that has an aggregation association to a derivation classifier. The derivation classifier will have a derivation to the template MyGeneric, and its binding will specify that argument is a String.
public class ClassA<TypeA> { }
public class ClassB<TypeB> extends ClassA<TypeB> { }
How to show such relationship on the Class diagram?
Posted by sunflower on March 09, 2007 at 04:05 AM MST #
Posted by Trey Spiva on March 09, 2007 at 07:09 AM MST #