简体   繁体   中英

Why casting direction is big to small in primitive types and small to big with objects?

In Java we need casting when converting double(big in memory size) to Integer (smaller in memory size)

int x = (int) 4.3;

But in case of objects if parent class is "Mammal"(small in memory size) and its subclass is "Human" (big in memory size since got more properties then mammal)

then

Mammal m = new Human(); //works without casting

but small to big conversion

Human h = (Human) m ; // needs casting 

Thanks in Advance.

Casting is not about the size of the object: it's about the range of the variable .

By 'range', i mean the variety of different values that the variable can contain. If you assign from one variable to another whose range is a superset of the first, you don't need to cast, because you know that the assignment will be okay. But when you assign from one variable to another whose range is a subset, you do need to cast, because the assignment might not be possible.

Imagine you have two containers: a plastic tub and a wire shopping basket, of the same size. Clearly, anything you can keep in the wire basket, you can keep in the tub. But not everything you can keep in the tub can be kept in the basket. A pile of apples, you can. But a pile of raisins, you can't - they would fall through the holes in the basket. So, the range of things that the tub can hold is greater than the range of things the basket can hold, even though both are the same size.

In that analogy, casting is like checking whether the thing you're moving will fit in the new container. You don't need to check when moving things from the basket to the tub, but you do need to check when moving from the tub to the basket, otherwise you will end up with fruit all over the floor.

In your specific cases, we know that every human is a mammal, but that not every mammal is a human, so the range of a variable of type Mammal is greater than that of a variable of type Human. We also know that the range of a double (approximately 2^1024 - -(2^1024)) is greater than that of an int (2^31-1 - -2^31). So, assigning from the former to the latter in either case requires a cast, but from the latter to the former does not.

When you use primitive types, you have to explicitely cast when there is a chance you might loose information. For example, long is 64 bits and int is 32. Converting a long in an int can result in data loss (32 bits in this case).

When dealing with objects, this is relative to polymorphism. The compiler is able to ensure that every Human is a Mammal . No problem here. But it is unable to ensure that every Mammal is a Human . You have to cast explicitely to convert the reference type.

You can see explicit casts as a way of saying to the compiler "I know you can't ensure this data conversion is safe, but I know what I am doing".

  1. In case of primitives memory comes into play.If you are going to store double into int as in your example, double takes more memory as compare to integer.So there is chance of data lose.So compiler throw error.If you cast yourself then you know what you are doing so compiler let that do.
  2. In case of object, No case of memory there.Just polymorphysm comes into play.So you can take a subclass object into supertype.

    Hope you will get it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM