Hello everyone. Today I want to talk about the PECS principle. I understand that now programming gurus and experienced seniors have once again pressed their hands in the face, because "Java Generics appeared in JDK 1.5, which was released on September 30, 2004 ...". But if there are those for whom the PECS principle remains vague and incomprehensible, and persistent googling only thickens the "fog", welcome to the cat, we will sort it out together until full spiritual enlightenment. I want to warn you right away that this article does not cover what generics are and what a wildcard is. If you are not familiar with these concepts, then you need to understand them before reading.
At first glance, it seems that the PECS principle is quite simple. Everyone who has met him knows that this is an acronym for Producer Extends Consumer Super. As explained in numerous articles, if we have a collection typed by a wildcard with an upper bound ( extends ), then this is the "producer". "It only 'produces', provides the element from the container, and does not receive anything by itself." If we have a collection typed by a wildcard on the lower boundary ( super ), then this is a “consumer” that “only accepts, but cannot provide anything”.
Well, that's actually all. Now we have mastered the "dark magic" of PECS and can safely go to an interview on Google to impress interviewers with our wisdom and experience. There is only one small formality left, to launch your favorite IDE and make sure that everything is the case for show: containers bounded by the upper border can only provide objects, and containers bounded by the lower border are only consumers.
For clarity, let's say we have a class hierarchy starting with Class0, which is the ancestor of Class1, which in turn is the ancestor of Class2, and so on. And there is a method that takes a wildcard-typed collection with an upper bound as an argument.
someMethod (List<? extends Class3> list)
According to the PECS principle, we cannot put anything in this sheet, it will only be the data provider.
List<? extends Class3> list
?
: , list, Class3, , list Class4, Class5, Class6 .. , – « »! :
public static void someMethod (List<? extends Class3> list) {
Class4 class4 = list.get(0);
}
:
public static void someMethod (List<? extends Class3> list) {
Class2 class2 = list.get(0);
}
: .
? ? - , , -. , . , . , Class3.
Class4 class4 = list.get(0);
- , -, Java . , , , , .
Class4 class4 = (Class4) list.get(0);
. ? ?
List<? extends Class3> list
(Class0, Class1, Class2), , : - -. List<Integer> list
, Number,
. , List<? extends Class3> list
Class4 Class5? ! JVM , List<? extends Class3>
. List<Class4>
, List<Class100500>
. List<Class100500>
, , Class3 Class4, , Number
List<Integer>
. , , List<? extends Class3>
Class3, - Class3, , , Class3.
PECS – «consumer super» («wildcard super — consumer, , »).
: wildcard super , wildcard extend – ? . List<? extends Class3>
- «» , List<? super Class3>
, «» Class3. ,
public static void someMethod (List<? super Class3> list) {
list.add(new Class4());
}
, :
public static void someMethod (List<? super Class3> list) {
list.add(new Class2());
}
, :
public static void someMethod (List<Integer> list) {
list.add(new Number());
}
, , «wildcard super — consumer » - . , , , «consumer super…»
public static void someMethod (List<? super Class3> list) {
list.get(0);
}
, -…
IDE, : , super, consumer! , , list.get(0)
. ? , Class3? ! , Class2 ( - super). ! Class4? . get()
, - ? «» Java - Object.
, PECS: , wildecard , Object?
, , , , , . , wildcard , , -, -.
«» ( Class2 Class3)
public static void someMethod (List<? super Class3> list) {
Class2 obj = list.get(0);
}
: List<Class1>
List<Object>
( <? super Class3>
) - (Class2 obj) (list.get(0)
). – , , Java, Object.
That's all I would like to tell you about the PECS principle. I hope my explanation came out clear and will help those who suffer the truth to understand this issue.