Create instance of generic type in Java?

后端 未结 27 3096
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-21 06:14

Is it possible to create an instance of a generic type in Java? I\'m thinking based on what I\'ve seen that the answer is no (due to type erasure), but

相关标签:
27条回答
  • 2020-11-21 07:02

    You are correct. You can't do new E(). But you can change it to

    private static class SomeContainer<E> {
        E createContents(Class<E> clazz) {
            return clazz.newInstance();
        }
    }
    

    It's a pain. But it works. Wrapping it in the factory pattern makes it a little more tolerable.

    0 讨论(0)
  • 2020-11-21 07:02

    You can do this now and it doesn't require a bunch of reflection code.

    import com.google.common.reflect.TypeToken;
    
    public class Q26289147
    {
        public static void main(final String[] args) throws IllegalAccessException, InstantiationException
        {
            final StrawManParameterizedClass<String> smpc = new StrawManParameterizedClass<String>() {};
            final String string = (String) smpc.type.getRawType().newInstance();
            System.out.format("string = \"%s\"",string);
        }
    
        static abstract class StrawManParameterizedClass<T>
        {
            final TypeToken<T> type = new TypeToken<T>(getClass()) {};
        }
    }
    

    Of course if you need to call the constructor that will require some reflection, but that is very well documented, this trick isn't!

    Here is the JavaDoc for TypeToken.

    0 讨论(0)
  • 2020-11-21 07:03
    package org.foo.com;
    
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    /**
     * Basically the same answer as noah's.
     */
    public class Home<E>
    {
    
        @SuppressWarnings ("unchecked")
        public Class<E> getTypeParameterClass()
        {
            Type type = getClass().getGenericSuperclass();
            ParameterizedType paramType = (ParameterizedType) type;
            return (Class<E>) paramType.getActualTypeArguments()[0];
        }
    
        private static class StringHome extends Home<String>
        {
        }
    
        private static class StringBuilderHome extends Home<StringBuilder>
        {
        }
    
        private static class StringBufferHome extends Home<StringBuffer>
        {
        }   
    
        /**
         * This prints "String", "StringBuilder" and "StringBuffer"
         */
        public static void main(String[] args) throws InstantiationException, IllegalAccessException
        {
            Object object0 = new StringHome().getTypeParameterClass().newInstance();
            Object object1 = new StringBuilderHome().getTypeParameterClass().newInstance();
            Object object2 = new StringBufferHome().getTypeParameterClass().newInstance();
            System.out.println(object0.getClass().getSimpleName());
            System.out.println(object1.getClass().getSimpleName());
            System.out.println(object2.getClass().getSimpleName());
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题