Code example for GenericArrayType

Methods: getGenericComponentType

0
            if (t instanceof Class)
                return onClass((Class)t,param);
            if (t instanceof ParameterizedType)
                return onParameterizdType( (ParameterizedType)t,param);
            if(t instanceof GenericArrayType)
                return onGenericArray((GenericArrayType)t,param);
            if(t instanceof WildcardType)
                return onWildcard((WildcardType)t,param);
            if(t instanceof TypeVariable)
                return onVariable((TypeVariable)t,param);
 
            // covered all the cases 
            assert false; 
            throw new IllegalArgumentException();
        } 
 
        protected abstract T onClass(Class c, P param);
        protected abstract T onParameterizdType(ParameterizedType p, P param);
        protected abstract T onGenericArray(GenericArrayType g, P param);
        protected abstract T onVariable(TypeVariable v, P param);
        protected abstract T onWildcard(WildcardType w, P param);
    } 
 
    /** 
     * Implements the logic for {@link #erasure(Type)}. 
     */ 
    private static final TypeVisitor<Class,Void> eraser = new TypeVisitor<Class,Void>() {
        public Class onClass(Class c,Void _) { 
            return c; 
        } 
 
        public Class onParameterizdType(ParameterizedType p,Void _) { 
            // TODO: why getRawType returns Type? not Class? 
            return visit(p.getRawType(),null); 
        } 
 
        public Class onGenericArray(GenericArrayType g,Void _) { 
            return Array.newInstance( 
                visit(g.getGenericComponentType(),null), 
                0 ).getClass(); 
        } 
 
        public Class onVariable(TypeVariable v,Void _) { 
            return visit(v.getBounds()[0],null); 
        } 
 
        public Class onWildcard(WildcardType w,Void _) { 
            return visit(w.getUpperBounds()[0],null); 
        } 
    }; 
 
    /** 
     * Returns the runtime representation of the given type. 
     * 
     * This corresponds to the notion of the erasure in JSR-14. 
     */ 
    public static <T> Class<T> erasure(Type t) {
        return eraser.visit(t,null);
    } 
 
    private static final TypeVisitor<Type,Class> baseClassFinder = new TypeVisitor<Type,Class>() {
        public Type onClass(Class c, Class sup) { 
            // t is a raw type 
            if(sup==c) 
                return sup; 
 
            Type r; 
 
            Type sc = c.getGenericSuperclass(); 
            if(sc!=null) { 
                r = visit(sc,sup); 
                if(r!=null)     return r; 
            } 
 
            for( Type i : c.getGenericInterfaces() ) { 
                r = visit(i,sup); 
                if(r!=null)  return r; 
            } 
 
            return null; 
        } 
 
        public Type onParameterizdType(ParameterizedType p, Class sup) { 
            Class raw = (Class) p.getRawType(); 
            if(raw==sup) { 
                // p is of the form sup<...> 
                return p; 
            } else { 
                // recursively visit super class/interfaces 
                Type r = raw.getGenericSuperclass(); 
                if(r!=null) 
                    r = visit(bind(r,raw,p),sup); 
                if(r!=null) 
                    return r; 
                for( Type i : raw.getGenericInterfaces() ) { 
                    r = visit(bind(i,raw,p),sup); 
                    if(r!=null)  return r; 
                } 
                return null; 
            } 
        } 
 
        public Type onGenericArray(GenericArrayType g, Class sup) { 
            // not clear what I should do here 
            return null; 
        } 
 
        public Type onVariable(TypeVariable v, Class sup) { 
            return visit(v.getBounds()[0],sup); 
        } 
 
        public Type onWildcard(WildcardType w, Class sup) { 
            // not clear what I should do here 
            return null; 
        } 
 
        /** 
         * Replaces the type variables in {@code t} by its actual arguments. 
         * 
         * @param decl 
         *      provides a list of type variables. See {@link GenericDeclaration#getTypeParameters()} 
         * @param args 
         *      actual arguments. See {@link ParameterizedType#getActualTypeArguments()} 
         */ 
        private Type bind( Type t, GenericDeclaration decl, ParameterizedType args ) { 
            return binder.visit(t,new BinderArg(decl,args.getActualTypeArguments())); 
        } 
    }; 
 
    private static final TypeVisitor<Type,BinderArg> binder = new TypeVisitor<Type,BinderArg>() {
        public Type onClass(Class c, BinderArg args) { 
            return c; 
        } 
 
        public Type onParameterizdType(ParameterizedType p, BinderArg args) { 
            Type[] params = p.getActualTypeArguments(); 
 
            boolean different = false; 
            for( int i=0; i<params.length; i++ ) { 
                Type t = params[i]; 
                params[i] = visit(t,args); 
                different |= t!=params[i]; 
            } 
 
            Type newOwner = p.getOwnerType(); 
            if(newOwner!=null) 
                newOwner = visit(newOwner,args); 
            different |= p.getOwnerType()!=newOwner; 
 
            if(!different)  return p; 
 
            return new ParameterizedTypeImpl( (Class<?>)p.getRawType(), params, newOwner ); 
        } 
 
        public Type onGenericArray(GenericArrayType g, BinderArg types) { 
            Type c = visit(g.getGenericComponentType(),types); 
            if(c==g.getGenericComponentType())  return g; 
 
            return new GenericArrayTypeImpl(c); 
        } 
 
        public Type onVariable(TypeVariable v, BinderArg types) {