Java 编译器强制原始使用参数化接口

Java compiler forcing raw use of paramatized interface

我正在尝试使用具体类型实现通用接口,但 java 编译器强制我将其实例化为原始接口。这是我的代码的模型:

public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("thing", "extra");
    Worker<String, String> worker = new Worker<>();
    worker.execute(map);
}

public class Worker<K, V> {
    public void execute(Map<K, V> map) {
        IDao<K, V> dao = new Dao();
        dao.doThing(map);
    }
}

public interface IDao<K, V> {
    void doThing(Map<K, V> map);
}

public class Dao implements IDao<String, String> {
    public void doThing(Map<String, String> map) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String newKey = key.toUpperCase();
            System.out.println(newKey + " " + entry.getValue());
        }
    }
}

如果我将 IDao<K, V> dao = new Dao(); 更改为 IDao dao = new Dao(),此代码将按预期工作,但这不是好的做法,我想避免它。我不明白为什么像这样在实例化时声明类型是非法的。

这个...

public class Worker<K, V> {
    public void execute(Map<K, V> map) {
        IDao<K, V> dao = new Dao();
        dao.doThing(map);
    }
}

我觉得不对。

Worker class 允许 Map 的通用 key/value 参数,但是,您正在实例化 Dao 的实例,该实例受约束至 <String, String>。这似乎是对合同的基本违反。

就我个人而言,我可能会更改此设置,以便将 IDao 的实例注入到 worker 中,例如...

public static class Worker<K, V> {
    
    private IDao<K, V> dao;

    public Worker(IDao<K, V> dao) {
        this.dao = dao;
    }

    public void execute(Map<K, V> map) {
        dao.doThing(map);
    }
}

nb:这可能是一个 abstract 工厂,它有一个 abstract 方法,类似于 abstract protected IDao<K, V> getDao(); 然后你必须提供一些具体的支持它的实现,但它基本上归结为同一件事

然后你就可以调用它做类似...

Map<String, String> map = new HashMap<>();
map.put("thing", "extra");
Worker<String, String> worker = new Worker<>(new Dao());
worker.execute(map);

当然,如果您不想这样做,那么您必须删除 Worker 的通用约束,并要求任何调用者将 Map 传递给 Map <String, String>

public static class Worker {
    public void execute(Map<String, String> map) {
        IDao<String, String> dao = new Dao();
        dao.doThing(map);
    }
}

可是现在,好处在哪里呢?