为什么铸造方向在原始类型中从大到小,从小到大与物体一起?

Mr *_*der 5 java oop casting object primitive-types

在Java中,我们需要在将double(内存大小)转换为Integer(内存大小更小)时进行转换

int x = (int) 4.3;
Run Code Online (Sandbox Code Playgroud)

但是在对象的情况下,如果父类是"哺乳动物"(内存大小很小)并且它的子类是"人类"(内存大小很大,因为它获得了更多属性,然后是哺乳动物)

然后

Mammal m = new Human(); //works without casting
Run Code Online (Sandbox Code Playgroud)

但从小到大的转换

Human h = (Human) m ; // needs casting 
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Tom*_*son 7

转换与对象的大小无关:它与变量范围有关.

"范围"是指变量可以包含的各种不同值.如果从一个变量分配到另一个变量,其范围是第一个变量的超集,则不需要强制转换,因为您知道赋值是可以的.但是当您从一个变量分配到另一个变量的范围是子集时,您需要进行强制转换,因为分配可能是不可能的.

想象一下,你有两个容器:一个塑料桶和一个相同大小的电线购物篮.显然,你可以保留在铁丝篮中的任何东西,你可以保持在浴缸里.但并不是所有可以放在浴缸里的东西都可以放在篮子里.一堆苹果,你可以.但是一堆葡萄干,你不能 - 它们会掉进篮子里的洞里.因此,浴缸可以容纳的东西范围大于篮子可容纳的范围,即使两者的大小相同.

在这个类比中,铸造就像检查你正在移动的东西是否适合新容器.您不需要检查什么时候将物品从篮子移到浴缸,但是您确实需要检查从浴缸移动到篮子的时间,否则您最终会在地板上找到水果.

在您的具体情况下,我们知道每个人都是哺乳动物,但并非每个哺乳动物都是人类,因此哺乳动物类型的变量范围大于人类的变量.我们还知道double(大约2 ^ 1024 - - (2 ^ 1024))的范围大于int(2 ^ 31-1 - -2 ^ 31)的范围.因此,在任何一种情况下,从前者到后者的分配需要一个演员,但从后者到前者则不需要.


Viv*_*sse 6

当您使用原始类型时,必须在有可能丢失信息时明确地进行转换.例如,long是64位并且int是32.转换a longin int会导致数据丢失(在这种情况下为32位).

处理对象时,这与多态性有关.编译器能够确保每个Human都是a Mammal.这里没问题.但它无法确保每一个Mammal都是一个Human.您必须明确地转换以转换引用类型.

你可以看到显式的强制转换作为对编译器的一种说法"我知道你不能确保这种数据转换是安全的,但我知道我在做什么".