可能是以前被问过的一个问题,但是像往常一样,第二个你提到通用单词,你会得到一千个解释类型擦除的答案.我很久以前就经历了这个阶段,现在就知道泛型及其使用情况,但是这种情况稍微更微妙一些.
我有一个容器表示电子表格中的数据单元格,实际上将数据存储为两种格式:作为显示字符串,也以另一种格式存储,取决于数据(存储为对象).该单元还保存一个变换器,该变换器在类型之间进行转换,并且还对类型进行有效性检查(例如,IntegerTransformer检查字符串是否为有效整数,并且是否返回存储的整数,反之亦然).
单元格本身没有键入,因为我想要更改格式(例如,将辅助格式更改为float而不是整数或原始字符串),而无需使用新类型重建单元对象.以前的尝试确实使用通用类型,但是无法改变类型,一旦定义,编码非常庞大,反映很多.
问题是:如何以类型方式将数据从我的单元格中取出?我尝试并发现,即使没有定义约束,也可以使用一种方法来使用通用类型
public class Cell {
private String stringVal;
private Object valVal;
private Transformer> trans;
private Class> valClass;
public String getStringVal(){
return stringVal;
}
public boolean setStringVal(){
//this not only set the value, but checks it with the transformer that it meets constraints and updates valVal too
}
public T getValVal(){
return (T) valVal;
//This works, but I don't understand why
}
}
让我失望的是:那是?它不能投掷任何东西,没有类型T的输入限制它匹配任何东西,实际上它什么都不说任何地方.拥有一个返回类型的对象只会给所有地方的铸造并发症.
在我的测试中,我设置一个Double值,它存储Double(作为一个对象),当我做了double testdou = testCell.getValVal();它立即工作,甚至没有被禁止的投射警告.但是,当我做了String teststr = testCell.getValVal()我得到一个ClassCastException.不真实的
有两种看法我看到:
一个:使用一个未定义的演员似乎只是一种风格的方式,将演员放在方法中,而不是在它返回之后.从用户的角度来看,这是非常整洁的,但该方法的用户必须担心使用正确的调用:所有这一切都是在隐藏复杂的警告和检查,直到运行时,但似乎工作.
第二个观点是:我不喜欢这个代码:它不干净,它不是那种代码质量我正常的自我写作.代码应该是正确的,不只是工作.应该抓住和处理错误,并且期望接口应该是万无一失的,即使唯一的期望用户是我自己,我总是喜欢灵活的通用和可重复使用的技术来尴尬的一个.问题是:有没有正常的方法呢?这是一个鬼祟的方式来实现无类型,所有接受ArrayList返回任何你想要的没有投射?还是有我在这里错过的东西.有东西告诉我,我不应该相信这段代码!
也许更多的是一个哲学问题比我想的,但我想这就是我在问的.
编辑:进一步测试.
我尝试了以下两个有趣的片段:
public T getTypedElem() {
T output = (T) this.typedElem;
System.out.println(output.getClass());
return output;
}
public T getTypedElem() {
T output = null;
try {
output = (T) this.typedElem;
System.out.println(output.getClass());
} catch (ClassCastException e) {
System.out.println("class cast caught");
return null;
}
return output;
}
当将double分配给typedElem并尝试将其放入String时,我会收到一个异常,而不是转换到,但在返回上,第二个代码段不保护. getClass的输出是java.lang.Double,表明这是从typedElem动态推断的,但编译器级别类型检查只是被迫离开了.
作为辩论的笔记:还有一个获取valClass的功能,这意味着可以在运行时进行可分配性检查.
编辑2:结果
在考虑了我使用两个解决方案的选项之后:一个轻量级解决方案,但将该功能注释为@depreciated,第二个解决方案是将您要尝试将其转换为的类.这样做是根据情况选择的.