Skip to content

mtumilowicz/java11-pecs-principle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status

java11-pecs-principle

Overview of PECS principle.

Reference: Effective Java: Joshua Bloch
Reference: https://howtodoinjava.com/java/generics/java-generics-what-is-pecs-producer-extends-consumer-super/

preface

Please refer my other github project: https://github.com/mtumilowicz/java11-covariance-contravariance-invariance

  • Covariance: ? extends Integer

    List<Integer> ints = new LinkedList<>();
    List<? extends Number> nums = ints;
    
  • Contravariance: ? super Integer

    List<Integer> ints = new LinkedList<>();
    List<? super Integer> nums = ints;
    
  • Invariance: neither covariant nor contravariant

    Generics are invarant

  • Remark:

    • covariance is read-only
    • contravariance is write-only
    • otherwise compile-time error

PECS stands for producer-extends, consumer-super:

  • Use the <? extends T> wildcard if you need to retrieve object of type T from a collection.
  • Use the <? super T> wildcard if you need to put objects of type T in a collection.

Properly used, wildcard types are nearly invisible to the users of a class (if the user of a class has to think about wildcard types, there is probably something wrong with its API.)

project description

We provide easy examples of PECS principle (and we show also examples of bad design - contradiction of PECS) in PECSTest:

  • producer
    • constructor of a LinkedList is a good example of producer
      public LinkedList(Collection<? extends E> c) {
          this();
          addAll(c);
      }
      
    • if we use side function with bad design
      private static <T> LinkedList<T> fromList_badDesign(Collection<T> list) { // it should be Collection<? extends T>
          return new LinkedList<>(list);
      }
      
      then
      LinkedList<Animal> dogs = fromList_badDesign(new LinkedList<Dog>()); // compile time error
      
    • if we use side function with good design
      private static <T> LinkedList<T> fromList_goodDesign(Collection<? extends T> list) {
          return new LinkedList<>(list);
      }
      
      then
      LinkedList<Animal> dogs = fromList_badDesign(new LinkedList<Dog>()); // OK!
      
  • consumer
    • addAll method of Collections is a good example of consumer
      boolean addAll(Collection<? super T> c, T... elements) {
          ...
      }
      
    • suppose we have collection of animals, we want to add a dog to it, but we don't want to add a dog to the cats of course.
      private static void addDog_goodDesign(Collection<? super Dog> c) {
          c.add(new Dog());
      }
      
      private static void addDog_badDesign(Collection<Dog> c) {
          c.add(new Dog());
      }
      
      private static void addDog_badDesign2(Collection<Animal> c) {
          c.add(new Dog());
      }
      
      then
      addDog_goodDesign(new LinkedList<Animal>());
      //        addDog_goodDesign(new LinkedList<Cat>()); // compile time error
      //        addDog_badDesign(new LinkedList<Animal>()); // compile time error
      //        addDog_badDesign2(new LinkedList<Dog>()); // compile time error
      
      note that collections are invariant so:
      addDog_badDesign2(new LinkedList<Dog>()); // compile time error
      

About

Overview of PECS principle.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages