为什么"TypeToken Collections"被认为是Typesafe?(有效的Java#29)

Dex*_*ter 4 java generics collections type-safety parametric-polymorphism

Effective Java中的第29项提供了一种实现"类型安全"异构集合的方法,它基本上归结为这样的东西:

public Class HeterogeneousContainer {
    private Map<Class<?>, Object> container = new HashMap<>();

    public <T> put(Class<T> type, T instance) {
        container.put(type, instance);
    }

    public <T> T get(Class<T> type) {
        //essentially just 
        //      return (T) container.get(type);
        return type.cast(container.get(type));
    }
}
Run Code Online (Sandbox Code Playgroud)

其中(我推测)就像这样(由制作人)使用:

List<HeterogeneousContainer> resultSet = new ArrayList<>();
...
resultSet.add(new HeterogeneousContainer());
...
resultSet.get(rowIndex).add(Column1.class, column1Value);
resultSet.get(rowIndex).add(Column2.class, column2Value);
...
Run Code Online (Sandbox Code Playgroud)

并且像这样(由消费者):

for(HeterogeneousContainer row:resultSet) {
    Column1 column1Value = row.get(Column1.class);
    Column2 column2Value = row.get(Column2.class);
    ...
    //do something with the columnValues
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是为什么这被认为类型安全?这比仅仅将列名放入地图还是只使用常规List/ List<Object>并按索引查找列更好?

这是否有效/实际上以任何方式改进了JDBC ResultsSets的.getString/.getInt/.getXXXX方法?

por*_*szd 5

这个类被认为是类型安全的,因为即使它在运行时进行类转换,这种不安全的行为也会被封装,你无法观察它.

  • container字段是私有的,因此在考虑类型安全时,您只需要检查此类中的代码.
  • put方法插入一对类型标记T 该类型的元素T.这是container更新的唯一位置,并且保证(在编译时)inserted元素具有正确的类型标记.
  • get方法确实类铸件以不安全的方式(return type.cast(container.get(type))),但只要它是保证,container只有通过修改put,它不能失败.在上面我们看到这put当然是唯一的方法,这个类对其用户来说类型安全的.

说实话,如果你真的想要,你可以打破这个类的类型安全性,例如使用反射.通常情况下这并不重要,因为你想要保护你的班级,因为他们被意外误用而不是故意破坏.但是,当您进一步阅读Effective Java时,您会发现防御此类攻击要复杂得多.