lundi 14 novembre 2016

How to get inner generic type dynamically

Now guys I have the following class:

import java.util.Collection;
import java.util.function.Function;

public class CollectionTypeParser<V extends Collection<P>,V1 extends Collection<R>,P, R> {
    private V collectionInput;
    private V1 collectionOutput;
    public CollectionTypeParser(V collectionInput,V1 collectionOutput) {
        this.collectionInput= collectionInput;
        this.collectionOutput= collectionOutput;
    }

    Function<P, R> fun=col->(R)col;
    public void parser(){
        collectionInput.stream().map(fun).forEach(e->collectionOutput.add(e));
    }
}

Which I use to switch from Collections with one type of values to another (parsing the values) if it is possible. Like in this example where Integers can be cast to String with no problems:

import java.util.HashSet;
import java.util.Set;

public class WorkTest {
    public static void main(String args[]) throws NoSuchFieldException, SecurityException {

        Set<String> b = new HashSet<String>();
        Set<Integer> a = new HashSet<Integer>();
        a.add(1);
        a.add(2);
        CollectionTypeParser<Set<Integer>, Set<String>, Integer, String> col = new CollectionTypeParser<Set<Integer>, Set<String>, Integer, String>(a, b);
        col.parser();
        System.out.println(a);
    }
}

Now this works. I end up with a SET of Strings which is what I want.

But I want to avoid using P and R. I know that in my constructor of CollectionTypeParser I can get those using some kind of reflection ? I am looking for solution that looks like this :

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.function.Function;

public class CollectionTypeParser<V extends Collection<?>, V1 extends Collection<?>> {
    private V collectionInput;
    private V1 collectionOutput;
    private Class<?> vGenericType;
    private Class<?> v1GenericType;

    public CollectionTypeParser(V collectionInput, V1 collectionOutput) {
        this.collectionInput = collectionInput;
        this.collectionOutput = collectionOutput;

        Field cI = WorkTest.class.getDeclaredField("collectionInput");
        ParameterizedType cIType = (ParameterizedType) cI.getGenericType();
        this.vGenericType = (Class<?>) cIType.getActualTypeArguments()[0];

        Field cO = WorkTest.class.getDeclaredField("collectionOutput");
        ParameterizedType cOType = (ParameterizedType) cO.getGenericType();
        this.v1GenericType = (Class<?>) cOType.getActualTypeArguments()[0];

    }

    Function<this.vGenericType, this.v1GenericType> fun = col -> (this.v1GenericType) col;

    public void parser() {
        collectionInput.stream().map(fun).forEach(e -> collectionOutput.add(e));
    }
}

But of course the way I wrote it is not even close but you get my point. Is this possible to do ?





Aucun commentaire:

Enregistrer un commentaire