Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java cant adding object in list without generic

Tags:

java

generics

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?

like image 323
Emre Akcan Avatar asked Dec 24 '22 10:12

Emre Akcan


1 Answers

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");)

like image 119
Thomas Avatar answered Dec 25 '22 22:12

Thomas