<div dir="auto"><div dir="auto"><br></div><div dir="auto">I was once again writing some generic Java class and suddenly I stand there again, I could not get the type of T.</div><div dir="auto"><br></div><div dir="auto">I’m sure this scenario sound familiar to every Java developer out there.</div><div dir="auto"><br></div><div dir="auto">If you first stumble across this problem type erasure comes up as the culprit: “Type T is not there at runtime it is replaced with Object”</div><div dir="auto"><br></div><div dir="auto">There are many solutions to this problem some hacky some require braking change to the generic system.</div><div dir="auto"><br></div><div dir="auto">Now my idea was why don’t we trace back the types at compile time? I mean every generic class is constructed somewhere in 6 possible ways:</div><div dir="auto"><br></div><div dir="auto">Foo<String> foo = new Foo<>();</div><div dir="auto">Foo<T> foo2 = new Foo<>();</div><div dir="auto">Foo foo3 = new Foo();</div><div dir="auto">Foo<?> foo4 = new Foo<>();</div><div dir="auto">Foo<? extends String> foo5 = new Foo<>();</div><div dir="auto">Foo<? super String> foo6 = new Foo<>();</div><div dir="auto">In case 1 we are already at our destination. The code the compiler gets contains the information we want. Why don’t we attach the type written in plain sight to the generic constructor?</div><div dir="auto"><br></div><div dir="auto">Like an implicit Foo<String> foo = new Foo<>(java.lang.String.class); (which explicitly is a current way of solving this. Which is in my opinion pretty ugly.)</div><div dir="auto"><br></div><div dir="auto">It would be syntactic sugar for the syntax above which spares the developers of repeating themselves. (just like <> does)</div><div dir="auto"><br></div><div dir="auto">If the compiler would just use the information he is erasing to fill it into the constructor. The only thing changing would be that the constructor would take 1 additional hidden argument and since the argument is filled at compile time it would not brake any code.</div><div dir="auto"><br></div><div dir="auto">In case 2 we are in some generic context like a nested class or a generic method. In both cases the actual type of T will be available. Such situations might require multiple passes to solve all dependencies. Then we can proceed like in 1.</div><div dir="auto"><br></div><div dir="auto">In case 3 we are dealing with legacy code and the type is always object. (Foo foo = new Foo(java.lang.Object))</div><div dir="auto"><br></div><div dir="auto">In case 4 we are dealing with an open type bound. The type is not constrained so we can only assume Object (Foo<?> foo = new Foo<>(java.lang.Object))</div><div dir="auto"><br></div><div dir="auto">In case 5 we have a upper constrained type bound. We can assume any Object passing that bound Is a subclass of String (Foo<? extends String> foo = new Foo<>(java.lang.String))</div><div dir="auto"><br></div><div dir="auto">In case 6 we have a lower constrained type bound. The Object passing this type bound could be Object. (Foo<? super String> foo = new Foo<>(java.lang.Object))</div><div dir="auto"><br></div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto">We would store the types at constructor or Method Invocation as arguments and then map them to the accessor T.class. This would allow type checking of T at runtime by tracing the real type at compile time.</div><div dir="auto"><br></div><div dir="auto">Since the type of T.class would be Class<T> or Class<?> we would not need to create a method or a class for each different version of the method or class like other languages do.</div><div dir="auto"><br></div><div dir="auto">I’m not quite sure how reflection is implemented but I’m sure there is a central invocation where the compiler could add the T.class argument. Of course we would need a way for reflection to specify the type T for this to work. We would simply need a method that is designed for generic classes like “<T> Constructor<T> getGenericConstructor(Class<?>[] typeParameterTypes, Class<?>… parameterTypes)” (could have a better signature).</div><div dir="auto"><br></div><div dir="auto">If the “getConstructor” is used on a generic class there would be a warning and the parameters would be set to Object (resulting in a raw object like any Objects generated by reflection currently are).</div><div dir="auto"><br></div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto">Risks:</div><div dir="auto"><br></div><div dir="auto">It would require the addition of n fields to any generic class or method where n stands for the number of generic arguments, which could result in performance and memory issues when adding this many new fields to the heap and stack. This issue could be reduced by only adding this mechanism when T.class or instanceof T are actually used in the context and would be skiped if the field is not used in the first place. Resulting in unchanged field count in all class files if the feature is used nowhere.</div><div dir="auto"><br></div><div dir="auto">Another rist would be the obvious change in class files, since the hidden arguments need to be stored at compile time near the invoke of the method/constructor.</div><div dir="auto"><br></div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto">This is just an idea based on my knowledge on generics in java.</div><div dir="auto"><br></div><div dir="auto">Please feel free to correct any misconceptions in this idea and tell me if I missed something.</div><div dir="auto"><br></div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto">Great regards</div><div dir="auto"><br></div><div dir="auto">RedIODev</div><div dir="auto"><br></div><div dir="auto"> </div><div dir="auto"><br></div><div dir="auto"><br></div></div>