java包装类(java.lang.Integer
,java.lang.Boolean
,...)背后的特殊原因是否没有常见的超类型?
我问,因为在经典WrapperType::getType
上有(例如)Object::getClass
函数会返回原始类型的类是非常方便的。
更具体地说,上下文是通过反射调用构造函数,其中只有Class<T>
和参数Object[]
E.g:
public static <T> T createInstance(Class<T> clz, Object... params) throws Exception
为了获得构造函数,我可以通过以下方式获取参数类型:
Class<?>[] c = Arrays
.stream(params)
.map(Object::getClass)
.toArray(Class<?>[]::new);
return clz.getConstructor(c).newInstance(params);
但这当然会因String::new(char[], int, int);
如果存在超类型,我可以这样做:
.map( o -> o.getClass().isPrimitive() ? ((WrapperType) o).getType() : o.getClass() )
我想有一个特殊原因java
开发人员没有实现它。
答案 0 :(得分:1)
Java设计人员的决策可能不是太抽象,并且在数字类型(例如Integer
)和非数字类型(例如Boolean
)之间找不到很多相似之处超类。
但是,所有数字类型都扩展Number
,它真正代表“可转换为基本类型byte
,double
,float
,{{1}的数值},int
,long
“。
实际上,所有包装类都有一个共同的接口short
(例如Comparable<T>
的{{1}}。)
答案 1 :(得分:1)
我可以看到这将是多么实际,但就抽象而言,这将是一个很大的混乱。让我们说你有包装Integer和Double以及那个家族中的其他人,他们确实有java.lang.Number作为他们的超级。然而,它们与布尔值之间没有语义关系(除了c影响)。
但是出于争论的缘故,让我们认为他们都在一个大桶里并且是Wrappers,他们还是数字吗?
考虑到语言历史上对多重继承的厌恶,如果你选择数字会产生更多的场景。
在使用SE 8进行语言功能的重大革命性变革之后,我们现在能够通过接口实现多重继承,同时使用标准实现来实现此类情况。如果进一步分析,他们将在逻辑推理中得出结论,这些案件要求合同而不是继承;因此,即使完成了,这也是接口的工作。
考虑到实现这一点的可靠方法是相当新的,并且Wrappers将是一种过于普遍的方式来实现它,我们可以看到最好不要拥有它。尽管现在已经成为可能,但是至少作为一个超级阶级,有一些历史和语义原因可以解释为什么它不是主持人。抽象是关键。但是没有什么可以阻止你在你的管道中插入工厂,或者实现上面提到的接口。
Buttom line,关键因素是: