pecs law in java generics

? extend

1 List<Apple> apples = new ArrayList<Apple>();
2 List<? extends Fruit> fruits = apples;
3 fruits.add(new Strawberry());

This time, the code doesn't compile! The Java compiler will prevent you from adding strawberry to a Fruit list. We can detect errors at compile time, and at runtime we don't need to check to make sure that incompatible types are added to the list. Even if you add Fruit objects to the list:

1 fruits.add(new Fruit());

You can't do this. In fact you can't write any value to a data structure using ? extends .

The reason is very simple, you can think of it this way: the ? extends T wildcard tells the compiler that we are dealing with a subtype of type T, but we don't know what that subtype is. Because there is no certainty, in order to ensure type safety, we are not allowed to add any data of this type to it. On the other hand, because we know that no matter what type it is, it is always a subtype of type T, and when we read data, we can be sure that the data we get is an instance of type T:

1 Fruit get = fruits.get(0);

? super

What is the general case for using the ? super wildcard? Let's look at this first:

1 List<Fruit> fruits = new ArrayList<Fruit>();
2 List<? super Apple> = fruits;

We see that fruits points to a List containing some of Apple's supertypes. Again, we don't know exactly what the superclass is, but we know that Apple and any Apple subclass are compatible with its type. Since this unknown type is Apple and is a superclass of GreenApple, we can write:

1 fruits.add(new Apple());
2 fruits.add(new GreenApple());

If we try to add Apple's superclass into it, the compiler will warn you:

1 fruits.add(new Fruit());
2 fruits.add(new Object());

Since we don't know what kind of superclass it is, all such instances are not allowed to join.

What about getting data from a type of this form? It turns out that you can only take out Object instances: since we don't know what the superclass actually is, the only thing the compiler can guarantee is that it's an Object, because Object is the superclass of any Java type.

Access Principles and PECS Laws

Summarizing the characteristics of ? extends and the ? super wildcard, we can draw the following conclusions:

  • If you want to get data from a data type, use the ? extends wildcard
  • If you want to write the object into a data structure, use the ? super wildcard
  • If you want to save and get it, don't use wildcards.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326138200&siteId=291194637