package utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; public class ReflectionExample { private Map<String, BonusColumn<? extends Object>> bonusColumns = new HashMap<>(); public static void main(String[] args) throws IOException { ReflectionExample foo = new ReflectionExample(); foo.start(); } public void start() throws IOException { // add bonus column, store type info: addBonusColumn("A", Integer.class); addBonusColumn("B", String.class); addBonusColumn("C", Date.class); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Please, select column A/B/C"); while(true) { String choice = br.readLine(); if (bonusColumns.containsKey(choice)) { BonusColumn<? extends Object> column = bonusColumns.get(choice); Class<? extends Object> typeInfo = column.typeInfo; // now what? // now what? // 1.)) old good case expression: switch(typeInfo.getCanonicalName()) { case "java.lang.Integer" : @SuppressWarnings("unchecked") BonusColumn<Integer> typeCasted = (BonusColumn<Integer>) column; // now we can use type cast typeCasted.addValue(34); Integer i = typeCasted.getHeadValue(); System.out.println("Pain in the butt: " + i); break; case "java.lang.String" : break; case "java.util.Date" : break; } // 2.)) virtual method (dispatches dynamically), not really helpful here // 3.)) there's no third choice } else { System.out.println("no such column " + choice); } } } public <T> void addBonusColumn(String name,Class<T> clazz){ BonusColumn<T> bonusColumnWithType = new BonusColumn<>(clazz); // it doesn't matter if it were new BonusColumn<Object>, it is the same as new BonusColumn<Int> !!!!! // it matters only compile-time!!! this.bonusColumns.put(name,bonusColumnWithType); } } // now remember that value for T is lost during erasure) class BonusColumn<T> { public final Class<T> typeInfo; private List<T> values = new ArrayList<>(); // or collection of values, doesn't matter public BonusColumn(Class<T> typeInfo) { this.typeInfo = typeInfo; } //public static <R> > public void addValue(T value) { values.add(value); } public T getHeadValue() { return values.get(0); } }