Сегодня наткнулся в Spring на класс ParameterizedTypeReference, который позволяет сохранять информацию об обобщенных типах. Javadoc к этому классу отправляет за подробностями в блог Нила Гафтера. Там я и нашел пример гетерогеносных коллекций, таких в которые можно складывать разные типы данных и при этом типобезопасно. Что мне позволило написать простенький пример в тематике баз данных:

package ru.yamakarov.examples;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Row {

    private Map<Column<?>, Object> attributes = new HashMap<>();

    public <T> void set(Column<T> column, T value) {
        attributes.put(column, value);
    }

    public <T> T get(Column<T> column) {
        return (T) attributes.get(column);
    }
}

abstract class Column<T> {

}


public class HeterogenousCollection {
    public static void main(String[] args) {
        Column<Integer> id = new Column<Integer>() {};
        Column<String> name = new Column<String>() {};
        Column<List<String>> addresses = new Column<List<String>>() {};

        Row row = new Row();

        // В id можно положить только число
        row.set(id, 1);
        // В name можно положить только строку
        row.set(name, "Yakov");
        // Можно класть не только reifable типы
        row.set(addresses, Arrays.asList("Питер", "Москва"));

        System.out.println(row.get(id).doubleValue());
        System.out.println(row.get(name).length());
        System.out.println(row.get(addresses).size());

    }
}

К сожалению я не до конца понимаю, работает это или нет. К тому же хочется как то заставить компилятор ругаться при попытке взять из ряда колонку, которой там не может быть.