Os genéricos Java (Generics) são um novo recurso introduzido no JDK5 que permite o uso de parâmetros de tipo (Type Parameter) ao definir classes e interfaces. Os parâmetros de tipo declarados são substituídos por tipos específicos quando usados. A aplicação mais importante de genéricos agora está na nova estrutura de classes de coleção no JDK5, onde Map e List são usados. As vantagens são evidentes. Podemos estender mais classes horizontalmente. As desvantagens são na verdade suas vantagens, pois quando usamos classes genéricas, devemos ser muito claros sobre o propósito do nosso código e não podemos usar erros de tipo.
A classe genérica mais básica
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e1;
/**
* A classe genérica mais básica, o tipo é definido por você mesmo
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Ponto<T> {
var T privado;
public T getVar() {
retornar var;
}
public void setVar(T var) {
isto.var = var;
}
}
pacote com.garinzhang.javabase.generic.e1;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Ponto<String> p = new Ponto<String>();
p.setVar("codificador");
System.out.println(p.getVar());
}
}
Vários tipos genéricos
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e2;
/**
* Vários tipos genéricos Geralmente, é melhor usar letras próximas de T, como S, R, etc.
* @autor Garin Zhang
*
* @param<T>
* @param<S>
*/
classe pública Bloco de notas<T, S> {
chave T privada;
valor S privado;
public T getKey() {
retorne esta.chave;
}
public S getValor() {
retorne este.valor;
}
public void setKey(chave T) {
esta.chave = chave;
}
public void setValue(valor S) {
este.valor = valor;
}
}
pacote com.garinzhang.javabase.generic.e2;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Bloco de notas<String, Inteiro> p = new Bloco de notas<String, Inteiro>();
p.setKey("codificador");
p.setValue(99999);
System.out.println("chave: " + p.getKey());
System.out.println("valor: " + p.getValue());
}
}
Use o curinga "?" nos parâmetros do método
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e3;
/**
* A chave para este exemplo está no método principal
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Informações<T> {
chave T privada;
public T getKey() {
retorne esta.chave;
}
public void setKey(chave T) {
esta.chave = chave;
}
@Substituir
string pública paraString() {
retornar this.key.toString();
}
}
pacote com.garinzhang.javabase.generic.e3;
/**
* Use curingas nos parâmetros do método
* @autor Garin Zhang
*
*/
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<String>i = new Info<String>();
i.setKey("codificador");
divertido(eu);
Info<Integer> j = new Info<Integer>();
j.setKey(9999);
diversão(j);
}
public static void fun(Info<?> temp) {
System.out.println("Conteúdo: " + temp);
}
}
A transformação ascendente falha
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e4;
/**
* A chave para este exemplo está no método principal
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Informações<T> {
chave T privada;
public T getKey() {
retorne esta.chave;
}
public void setKey(chave T) {
esta.chave = chave;
}
@Substituir
string pública paraString() {
retornar this.key.toString();
}
}
pacote com.garinzhang.javabase.generic.e4;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
Info<Objeto> objEg;
// Erro de compilação "Tipo incompatível: não é possível converter de Info<String> para Info<Object>"
//Upcast falhou, String -> Objeto
// objEg = strEg;
}
}
O uso de genéricos em interfaces
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e5;
/**
* A chave para este exemplo está no método principal
* @autor Garin Zhang
*
* @param<T>
*/
informações da interface<T> {
public T getVar();
}
pacote com.garinzhang.javabase.generic.e5;
/**
* Classe genérica
* @autor Garin Zhang
*
* @param<T>
*/
classe pública InfoImpl<T> implementa Info<T> {
var T privado;
public InfoImpl(T var) {
this.setVar(var);
}
public void setVar(T var) {
isto.var = var;
}
public T getVar() {
retorne isto.var;
}
}
pacote com.garinzhang.javabase.generic.e5;
/**
* Classe não genérica
* @autor Garin Zhang
*
* @param<T>
*/
A classe pública InfoImpl1 implementa Info<String> {
string privada var;
public InfoImpl1(String var) {
this.setVar(var);
}
public void setVar(String var) {
isto.var = var;
}
string pública getVar() {
retorne este.var;
}
}
pacote com.garinzhang.javabase.generic.e5;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<String> strEg = new InfoImpl<String>("codificador");
System.out.println("Conteúdo: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("coder1");
System.out.println("Conteúdo: " + strEg1.getVar());
}
}
Curingas e o uso de extends e super
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e6;
/**
* A chave para este exemplo está no método principal
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Informações<T> {
chave T privada;
public T getKey() {
retorne esta.chave;
}
public void setKey(chave T) {
esta.chave = chave;
}
@Substituir
string pública paraString() {
retornar this.key.toString();
}
}
pacote com.garinzhang.javabase.generic.e6;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<String> strEg = new Info<String>();
strEg.setKey("codificador");
//Erro de compilação "O método fun(Info<? extends Number>) no tipo GenericExample não é aplicável aos argumentos (Info<String>)"
//upTypeLimit(i);
//Use os tipos Inteiro ou Número.
Info<Integer> intEg = new Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
//Erro de compilação "O método downTypeLimit(Info<? super String>) no tipo GenericExample não é aplicável aos argumentos (Info<Integer>)"
//downTypeLimit(intEg);
// Como super é usado, downTypeLimit só pode receber String e Object
// Verificado o relacionamento de herança de String, nenhuma outra classe é herdada, apenas Object
downTypeLimit(strEg);
Info<Objeto> objEg = new Info<Objeto>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* <? extends T> representa o limite superior do tipo, indicando que o tipo parametrizado pode ser T ou uma subclasse de T
* @param temperatura
*/
public static void upTypeLimit(Info<? estende número> temp) {
System.out.println("Conteúdo: " + temp);
}
/**
* <? super T> representa o limite inferior do tipo (chamado de qualificação de supertipo no Java Core), indicando que o tipo parametrizado é o supertipo (tipo pai) deste tipo, até Object
* Neste exemplo, significa que T só pode ser Object ou String, pois String só herda de Object
* @param temperatura
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("Conteúdo: " + temp);
}
}
Genéricos de método, vários genéricos no método
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e7;
/**
* Método genérico, vários genéricos no método
* @autor Garin Zhang
*
* @param<T>
*/
Informações da classe pública {
/**
* Formato: modificação do método <lista de tipos separados por vírgula> tipo de valor de retorno nome do método (lista de parâmetros)
* Por exemplo: public <T, S> T fun(T t, S s)
* @param t
* @params
* @retornar
*/
público <T, S> T divertido(T t, S s) {
System.out.println(s.toString());
retornar t;
}
}
pacote com.garinzhang.javabase.generic.e7;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Informações informações = new Informações();
String str = info.fun("coder", "imprimir segundo parâmetro genérico");
System.out.println(str);
int i = info.fun(30, "imprimir o segundo parâmetro novamente");
System.out.println(i);
}
}
O tipo genérico passado ou retornado no método é determinado pelo tipo de parâmetro definido quando o método é chamado.
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e8;
/**
* estende
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Info<T estende número> {
var T privado;
public T getVar() {
retorne isto.var;
}
public void setVar(T var) {
isto.var = var;
}
@Substituir
string pública paraString() {
retornar this.var.toString();
}
}
pacote com.garinzhang.javabase.generic.e8;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); // O tipo aqui foi determinado como Integer
System.out.println(intEg.getVar());
}
/**
* O tipo genérico passado ou retornado no método é determinado pelo tipo de parâmetro definido ao chamar o método.
* @param param
* @retornar
*/
public static <T estende Número> Info<T> fun(T param) {
Info<T> temp = new Info<T>();
temp.setVar(param);
temperatura de retorno;
}
}
Torne os dois tipos de parâmetros passados no método consistentes
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e9;
/**
* Ver principal
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Informações<T> {
var T privado;
public T getVar() {
retorne isto.var;
}
public void setVar(T var) {
isto.var = var;
}
@Substituir
string pública paraString() {
retornar this.var.toString();
}
}
pacote com.garinzhang.javabase.generic.e9;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Info<String> i1 = new Info<String>();
i1.setVar("Olá");
Info<String> i2 = new Info<String>();
i2.setVar("Codificador");
Info<Integer> i3 = new Info<Integer>();
i3.setVar(999);
adicionar(i1,i2);
//Erro de compilação "O método add(Info<T>, Info<T>) no tipo GenericExample não é aplicável aos argumentos (Info<String>, Info<Integer>)"
//adicionar(i1,i3);
}
/**
* Os dois tipos de parâmetros passados no método devem ser consistentes
* @param param
* @retornar
*/
public static <T> void add(Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
Genéricos, parâmetros variáveis, semelhantes ao objeto Arguments em JavaScript
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e10;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Inteiro i[] = diversão(1, 2, 3, 4, 5, 6);
diversão2(eu);
}
public static <T> T[] fun(T... arg) {
retornar argumento;
}
public static <T> void fun2(T param[]) {
System.out.println("matriz genérica: ");
para(T t : parâmetro) {
System.out.println(t + ",");
}
}
}
Aninhamento genérico: use classes genéricas como parâmetros para determinar o valor de retorno com base no tipo de valor de retorno;
Copie o código do código da seguinte forma:
pacote com.garinzhang.javabase.generic.e11;
/**
* Aceita dois tipos genéricos
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Informações<T, V> {
var T privado;
valor V privado;
public T getVar() {
retorne isto.var;
}
public void setVar(T var) {
isto.var = var;
}
público V getValor(){
retorne este.valor;
}
public void setValue(valor V) {
este.valor = valor;
}
@Substituir
string pública paraString() {
retornar this.var.toString();
}
}
pacote com.garinzhang.javabase.generic.e11;
/**
* Aceita 1 tipo genérico
* @autor Garin Zhang
*
* @param<T>
*/
classe pública Demo<S> {
informações S privadas;
demonstração pública (informações S) {
this.setInfo(informações);
}
public void setInfo(S info) {
isto.info = informação;
}
public S getInfo() {
retorne este.info;
}
}
pacote com.garinzhang.javabase.generic.e11;
importar java.util.List;
importar com.google.common.collect.Lists;
classe pública Exemplo Genérico {
/**
* @param argumentos
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
Info<String, Inteiro> i;
i = new Info<String, Inteiro>();
i.setVar("Codificador");
i.setValue(999);
d = new Demo<Info<String,Integer>>(i);
System.out.println("Conteúdo: " + d.getInfo().getVar());
System.out.println("Conteúdo: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString());
// Aviso "Segurança de tipo: Um array genérico de Object&Comparable<?>&Serializable é criado para um parâmetro varargs"
System.out.println(query(1, 2, 3, "StringType").toString());
System.out.println(query("I ", "am", "a", "coder").toString());// [I , am , a , codificador]
List<String> list = Lists.newArrayList("I ", "sou", "a", "codificador");
System.out.println(list.toString()); // [Eu, sou, um, codificador]
}
/**
* Determine o tipo genérico por meio do valor de retorno O tipo de valor de retorno neste método é gerado automaticamente pela definição do método.
* Elementos @param
* @retornar
*/
public static <E> Lista<E> consulta(E...elementos) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
//importar com.google.common.collect.Lists;
// <dependência>
// <groupId>com.google.guava</groupId>
// <artifactId>goiaba</artifactId>
// <versão>16.0.1</versão>
// </dependency>
retornar Lists.newArrayList(elementos);
}
}