Olá a todos. Hoje quero falar sobre o princípio PECS. Eu entendo que agora gurus da programação e idosos experientes pressionaram mais uma vez na cara, porque "Java Generics apareceu no JDK 1.5, que foi lançado em 30 de setembro de 2004 ...". Mas se há aqueles para quem o princípio PECS permanece vago e incompreensível, e o googling persistente apenas torna a "névoa", bem-vindo ao gato, nós resolveremos isso juntos até a iluminação espiritual completa. Quero avisar imediatamente que este artigo não cobre o que são genéricos e o que é um caractere curinga. Se você não está familiarizado com esses conceitos, precisa entendê-los antes de ler.
À primeira vista, parece que o princípio PECS é bastante simples. Todos que o conheceram sabem que se trata de um acrônimo para Producer Extends Consumer Super. Conforme explicado em vários artigos, se tivermos uma coleção digitada por um caractere curinga com um limite superior ( estende ), então esse é o "produtor". "Ele apenas 'produz', fornece o elemento do contêiner e não recebe nada por si mesmo." Se tivermos uma coleção digitada por um caractere curinga no limite inferior ( super ), então este é um “consumidor” que “apenas aceita, mas não pode fornecer nada”.
Bem, isso é realmente tudo. Agora, dominamos a "magia negra" do PECS e podemos ir com segurança a uma entrevista no Google para impressionar os entrevistadores com nossa sabedoria e experiência. Resta apenas uma pequena formalidade, para lançar seu IDE favorito e ter certeza de que tudo é o caso para mostrar: os contêineres delimitados pela borda superior podem fornecer apenas objetos, e os contêineres limitados pela borda inferior são apenas consumidores.
Para maior clareza, digamos que temos uma hierarquia de classes começando com Class0, que é o ancestral de Class1, que por sua vez é o ancestral de Class2 e assim por diante. E há um método que usa uma coleção de caracteres curinga com um limite superior como argumento.
someMethod (List<? extends Class3> list)
De acordo com o princípio PECS, não podemos colocar nada nesta ficha, será apenas o fornecedor dos dados.
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.
Isso é tudo que eu gostaria de dizer sobre o princípio PECS. Espero que minha explicação tenha ficado clara e ajude aqueles que sofrem com a verdade a entender esse problema.