Re: generic'i
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 21.05.07 10:48
Оценка: 2 (1)
Здравствуйте, stenkil, Вы писали:

S>...


S>Помогите примером, а то в общем по отдельности все понятно, а вместе


1. Не надо (даже в тестовых примерах) использовать некомпилируемый код (нельзя использовать ключевые слова в качестве названий классов/полей/методов etc — метод do(); switch работает только с is-a int и enum);

2. Пример:

package com;

import javax.naming.NamingException;
import java.util.Map;
import java.util.HashMap;

/**
 * @author Denis Zhdanov
 * @since 27.04.2007
 */
public class AAA {
    public static void main(String[] args) throws NamingException, ClassNotFoundException {
        CommandFactory factory = new CommandFactory();
        Service<Integer, String> service1 = factory.getService(Command.COMMAND_1);
        Service<String, Boolean> service2 = factory.getService(Command.COMMAND_2);
        String s = service1.doWork(1);
        Boolean b = service2.doWork("asdf");
    }
}

interface Service<K, V> {
    V doWork(K param);
}

class Command<K, V> {
    public static final Command<Integer, String> COMMAND_1 = new Command<Integer, String>();
    public static final Command<String, Boolean> COMMAND_2 = new Command<String, Boolean>();

    private Command() {
    }
}

class CommandFactory {

    private final Map<Command, Service> services = new HashMap<Command, Service>();

    @SuppressWarnings("unchecked")
    public <K, V> Service<K, V> getService(Command<K, V> command) throws IllegalStateException {
        if (!services.containsKey(command)) {
            throw new IllegalStateException("No service defined for command '" + command + "'. "
                    + "Available mappings: " + services);
        }
        return services.get(command);
    }

    {
        storeMapping(Command.COMMAND_1, new Service1());
//        storeMapping(Command.COMMAND_1, new Service2()); // (1)
//        services.put(Command.COMMAND_1, new Service2()); // (2)
        storeMapping(Command.COMMAND_2, new Service2());
    }

    /**
     * Stores mapping for given command and service. Is introuced in order to process compile-time
     * type safety checking.
     *
     * @param command   command to store
     * @param service   service to store
     */
    private <K, V> void storeMapping(Command<K, V> command, Service<K, V> service) {
        services.put(command, service);
    }
}

class Service1 implements Service<Integer, String> {
    public String doWork(Integer param) {
        return "aasd";
    }
}

class Service2 implements Service<String, Boolean> {
    public Boolean doWork(String param) {
        return false;
    }
}


Здесь есть два тонких момента:

1. Поскольку сейчас стандартная библиотека не предлагает type-safe map, у которой entry может содержать ссылки разных типов, мы помечаем CommandFactory.getService() @SuppressWarnings("unchecked"). Т.е. мы знаем, что у нас в Map лежат корректные связки типов и просим компилятор не беспокоиться;

2. Для того, чтобы обеспечить поддержку того, что в Map лежат пары ключ-значения правильных типов (т.е. для каждой пары типу ключа соответствует правильный тип значения), мы кладем не напрямую через put(), а через storeMapping(). Здесь можно откомментировать (1) и (2) и увидеть, что при (1) получим ошибку, а при (2) нет;
http://denis-zhdanov.blogspot.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.