I found a lot of posts about how to overcome this limitation, but none about why this limitation exists (except this one, which just mentions it has to do with type era
Remember that generic types are about compile-time safety. Compile-time checking of types allows the compiler to give you warnings/errors about issues with your code. This doesn't directly help your question, but it's important to keep the concepts of compile-time and runtime very clear.
You can't say, "return new T()
" because the compiler has no way of knowing how to do that. Without the specific type, the compiler can't know what constructor to call or even if it exists. Also, in order to "new up" an instance of type T
you need something to call. T
is just a symbol. It isn't a Class
or an Object
. Until you give information about what kind of instance T
is (eg List
) the compiler has no way of doing what you are trying to do.
Typing is just a way of ensuring that the types given and returned will match correctly at compile-time. It's when you specify type specifics that you are able to create an instance of it. That's why you usually see completely open types on interfaces (eg List
, Function
etc). So implementers of the interface can specify what types will used.
Maybe it helps to think about generics like templates. Not the software development pattern, but the more abstract concept. The concept of a template says there's this structure without any internal details. If you want to create this thing that follows the template, use the template as your starting point, but you must fill in the details to make the thing. A generic type is sort of like that -- it allows you to structure something but doesn't give any details about what happens in that structure.
I know I struggled quite a bit with this when generics were introduced. At first I found it easiest to write the implementation for specific types first and then abstract it out using generics afterwards. After I got my head around generics, I now find it easier to start with a generified interface and then implement it.