wutzebaer wutzebaer - 1 month ago 11
Java Question

Inline class which extends a type parameter

I want to write a quick and dirty helper class which can quickly save my objects. Therefore I'm using OrmLite.

I don't want to add annotations on my classes, so I try to add a wrapper on the fly, without any bytecode-libs.

<T> void save(T o) {
@DatabaseTable
class wrap extends T {
@DatabaseField(generatedId = true)
public Long id;
}

try {
Dao<T, Long> d = (Dao<T, Long>) getClassDao(o.getClass());
TableUtils.createTableIfNotExists(connectionSource, o.getClass());
d.createOrUpdate(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}


The problem is
class wrap extends T
- why is it not possible to extend
T
?

Lii Lii
Answer

This is a weird but interesting question! It's tricky to give an exact and exhaustive answer. There are probably a lot of different reasons, but I think the following one is the most important:

Only one version of save will ever be generated by the compiler. For class wrap extends T to work the parameter T would have to be a different concrete classes for every use of save with a different type, but that is not how generics work. save is compiled only one time, and inside save T is a type parameter, not a concrete type. (This is somewhat related to, but different from type erasure, see below.)

Another reason is type erasure. Generic types in Java is something that only exists at compile time. A class in Java on the other hand has a runtime representation (in contrast to, for example, C++). So there is no possibility that the runtime representation of a class could be generated from the compile-time-only construct that a generic type is.

Comments