Factory Method 패턴을 적용할때 이용하면 유용할 것 같다.
public interface Generator<T> {
    T next();
}

public class CoffeeGenerator implements Generator<Coffee> {
    private Class[] types = {Latte.class, Mocha.class, 
Cappuccino.class, Americano.class};
    private static Random random = new Random(47);

    public CoffeeGenerator() {
    }

    public Coffee next() {
        try {
            return (Coffee) types[random.nextInt(types.length)].newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static void main(String[] args) {
        CoffeeGenerator gen = new CoffeeGenerator();
        for(int i=0; i<5; i++) {
            System.out.println(gen.next());
        }
    }
}

제너릭 메소드
public class GenericMethods {
    public <T> void f(T t) {
        System.out.println(t.getClass().getName());
    }
    
    public static void main(String[] args) {
        GenericMethods genericMethods = new GenericMethods();
        genericMethods.f("");
        genericMethods.f(1);
        genericMethods.f(1.0);
        genericMethods.f(genericMethods);
    }
}
결과
java.lang.String
java.lang.Integer
java.lang.Double
generic.GenericMethods

타입인자추론 : 우리가 코드를 되풀이하여 작성하게 되서 좀 귀찮은 경우가 있다.
Map<String, Object> params = new HashMap<String, Object>();
아래와 같이 구현하면 더 깔끔해 질것 같다.
public class New {
    public static <K, V> Map<K, V> map() {
        return new HashMap<K, V>();
    }
    
    public static <T> List<T> list() {
        return new ArrayList<T>();
    }
    
    //사용 예
    public static void main(String[] args) {
        Map<String, Object> params = New.map();
        List<String> list = New.list();
    }
}