Why should I care that Java doesn't have reified generics?

后端 未结 13 718
予麋鹿
予麋鹿 2020-11-28 02:59

This came up as a question I asked in an interview recently as something the candidate wished to see added to the Java language. It\'s commonly-identified as a pain that Jav

相关标签:
13条回答
  • 2020-11-28 03:16

    You'd be able to create generic arrays in your code.

    public <T> static void DoStuff() {
        T[] myArray = new T[42]; // No can do
    }
    
    0 讨论(0)
  • 2020-11-28 03:16

    My exposure to Java Geneircs is quite limited, and apart from the points other answers have already mentioned there is a scenario explained in the book Java Generics and Collections, by Maurice Naftalin and Philip Walder, where the reified generics are useful.

    Since the types are not reifiable, it is not possible to have Parameterized exceptions.

    For example the declaration of below form is not valid.

    class ParametericException<T> extends Exception // compile error
    

    This is because the catch clause checks whether the thrown exception matches a given type. This check is same as the check performed by instance test and since the type is not reifiable the above form of statement is invalid.

    If the above code was valid then exception handling in the below manner would have been possible:

    try {
         throw new ParametericException<Integer>(42);
    } catch (ParametericException<Integer> e) { // compile error
      ...
    }
    

    The book also mentions that if Java generics are defined similar to the way C++ templates are defined (expansion) it may lead to more efficient implementation as this offers more opportunities for optimization. But doesn't offer any explanation more than this, so any explanation (pointers) from the knowledgeable folks would be helpful.

    0 讨论(0)
  • 2020-11-28 03:18

    From the few times that I came across this "need", it ultimately boils down to this construct:

    public class Foo<T> {
    
        private T t;
    
        public Foo() {
            this.t = new T(); // Help?
        }
    
    }
    

    This does work in C# assuming that T has a default constructor. You can even get the runtime type by typeof(T) and get the constructors by Type.GetConstructor().

    The common Java solution would be to pass the Class<T> as argument.

    public class Foo<T> {
    
        private T t;
    
        public Foo(Class<T> cls) throws Exception {
            this.t = cls.newInstance();
        }
    
    }
    

    (it does not necessarily need to be passed as constructor argument, as a method argument is also fine, the above is just an example, also the try-catch is omitted for brevity)

    For all other generic type constructs, the actual type can easily be resolved with a bit help of reflection. The below Q&A illustrate the use cases and possibilities:

    • Get generic type of java.util.List
    • How to get the generic type at runtime?
    • Get actual type of generic type argument on abstract superclass
    0 讨论(0)
  • 2020-11-28 03:20

    This is an old question, there are a ton of answers, but I think that the existing answers are off the mark.

    "reified" just means real and usually just means the opposite of type erasure.

    The big problem related to Java Generics:

    • This horrible boxing requirement and disconnect between primitives and reference types. This isn't directly related to reification or type erasure. C#/Scala fix this.
    • No self types. JavaFX 8 had to remove "builders" for this reason. Absolutely nothing to do with type erasure. Scala fixes this, not sure about C#.
    • No declaration side type variance. C# 4.0/Scala have this. Absolutely nothing to do with type erasure.
    • Can't overload void method(List<A> l) and method(List<B> l). This is due to type erasure but is extremely petty.
    • No support for runtime type reflection. This is the heart of type erasure. If you like super advanced compilers that verify and prove as much of your program logic at compile time, you should use reflection as little as possible and this type of type erasure shouldn't bother you. If you like more patchy, scripty, dynamic type programming and don't care so much about a compiler proving as much of your logic correct as possible, then you want better reflection and fixing type erasure is important.
    0 讨论(0)
  • 2020-11-28 03:20

    It's not that you will achieve anything extraordinary. It will just be simpler to understand. Type erasure seems like a hard time for beginners, and it ultimately requires one's understanding on the way the compiler works.

    My opinion is, that generics are simply an extra that saves a lot of redundant casting.

    0 讨论(0)
  • 2020-11-28 03:21

    Something that all the answers here have missed that is constantly a headache for me is since the types are erased, you cannot inherit a generic interface twice. This can be a problem when you want to make fine grained interfaces.

        public interface Service<KEY,VALUE> {
               VALUE get(KEY key);
        }
    
        public class PersonService implements Service<Long, Person>,
            Service<String, Person> //Can not do!!
    
    0 讨论(0)
提交回复
热议问题