简体   繁体   中英

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 ?

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.

<T> is a generic type, not a real class. A generic type is a compile time concept, it get erased at runtime, while a class is a runtime stuff and it does have corresponding bytecode. You can't declare a sub class of generic type <T> because compiler has no idea what that super class is

Because T could be final. Final classes cannot be extended.

At least this is a logical reason that prohibits extending a generic type. The technical background is explained in other answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM