Runtime-Generics
I’m a heavy user of generalized classes and interfaces in Java.Sadly, the generalization is only for compile-time checks. But because you can cast any parameterized class-instance to an unchecked instance you can fool the system. This can be very annoying if a class-cast exception occurs later. For example with collections, the ClassCastException happens somewhere later and the stacktrace points to the wrong location.
Well for Collections there is a simple solution available. You can create runtime-checked Collections with the Collections-class
List<String> test = Collections.checkedList(new ArrayList<String>(),String.class);
List somewhereElse = test;
somewhereElse.add(44); // Here the ClassCastException will be thrown
The bad thing is, this is made just for collections. Now I’m thinking about creating an small library, which can create runtime-checks for any interface. Since I saw the little trick on the Google-Guice-library, this seems to be solvable. Sure, you have to use some dirty tricks to archive this goal, but maybe it is realizable.
The following code-snippet shows, what I’m thinking of:
// This is our target-type
Task<Map<String, ?>, List<? extends InputStream>> targetType;
// To create in the code, we create an inner-class of the Type-interface.
// This type will be interpreted by the system to create the typed version.
// Then we bind it the the normal implementation class and create an instance at the end.
targetType =
RuntimeTypeSave.create(new Type<Task<Map<String, ?>, List<? extends InputStream>>>() {})
.bindTo(new HashMap())
.createInstance();
And the code for more dynamic creation, for example when you create a typed based on configuration:
// There has to be a possibility to create the same type complete dynamically.
// Because the type may get constructet depending on a configuration.
// Build the first parameter The Type.ANY_TYPE represents the ? on the parameterlist.
Builder<Map> firstParam = RuntimeTypeSave.getBuilder(Map.class);
Type firstType = firstParam.setParameters(String.class, Type.ANY_TYPE.class).createType();
// Create the second parameter
Builder<List> secondParam = RuntimeTypeSave.getBuilder(List.class);
Type secondType = secondParam.extendsFrom(InputStream.class).createType();
// Create the final type
Type<Task> finalType = RuntimeTypeSave
.getBuilder(Task.class).setParameters(firstType, secondType)
.createType();
// Ugly cast =(
targetType = (Task<Map<String,?>, List<? extends InputStream>>) RuntimeTypeSave.create(finalType).
bindTo(new TaskImpl()).createInstance();
- Wiki
- Dead Like Me Movie