I have those classes.
public class Flight {
public List<FlightOffer> flightOffers;
}
public class Hotel<T> {
public List<HotelOffer> hotelOffers;
public T address
}
public class FlightOffer extends BaseOffer{
}
public class HotelOffer extends BaseOffer{
}
public class BaseOffer{
public String id;
}
flightOffers and hotelOffers returns a list.
Flight flightObject = new Flight();
flightObject.flightOffers.add(new BaseOffer()); // not working
//(add (FlightOffer) List cannot be applied to (BaseOffer))
Hotel hotelObject = new Hotel<String>();
hotelObject.hotelOffers.add(new BaseOffer()); // working
but if i convert Flight to Flight<T> its working, why?
List<FlightOffer> flightOffers defines quite clearly what you can add to the list: instances of FlightOffer. flightOffers.add(new BaseOffer()); hence can't work since a BaseOffer is not a FlightOffer.
So why does hotelOffers.add(new BaseOffer()); work? Because you are disabling generic type checks by using the raw type Hotel in Hotel hotelObject = new Hotel<String>();.
You should get a warning about that as well which conveys another lesson: don't ignore the warnings. The compiler doesn't know that something will fail but more often than not it "guesses" correctly and warns you about that.
Edit:
Note what the JLS states on raw types (in the first box of section 4.8):
Another implication of the rules above is that a generic inner class of a raw type can itself only be used as a raw type.
That means that because Hotel is a raw type, every generic type inside it can also only be a raw type, i.e. hotelOffers is treated as if it were a raw List which allows any type of object (thus even this should work in your code hotelObject.hotelOffers.add("I'm not a hotel offer");)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With