O que significa a natureza genérica da classe? O que é T?

Entendo os genéricos quando se trata de colecções. Mas o que significa no caso da turma? Quando se instancia um objecto Class, só há um objecto. Então, porquê o parâmetro T? O que está a especificar? E por que é necessário (se é)?

Author: Paul Bellora, 2012-02-23

4 answers

O parâmetro do tipo <T> foi adicionado a java.lang.Class para permitir um idioma específico.1 - utilização de Class objectos como fábricas de objectos seguros do tipo. Essencialmente, a adição de <T> permite-lhe instanciar classes de uma forma segura de tipo, como esta:

T instance = myClass.newInstance();

O parâmetro do tipo <T> representa a própria classe, permitindo-lhe evitar efeitos desagradáveis do tipo de apagamento, armazenando Class<T> numa classe genérica ou passando-a como parâmetro para um método genérico. Note que T por si só não seria suficiente para completar esta tarefa2: o tipo de T é apagado, por isso torna-se java.lang.Object debaixo do capô.

Aqui está um exemplo clássico onde {[[2]} parâmetro da classe se torna importante. No exemplo abaixo, o compilador Java é capaz de garantir a segurança do tipo, permitindo que você produza uma coleção digitada de uma string SQL e uma instância de Class<T>. Note-se que a classe é utilizada como uma fábrica , e que a sua segurança de tipo pode ser verificada na compilação tempo:

public static <T> Collection<T> select(Class<T> c, String sqlStatement) {
    Collection<T> result = new ArrayList<T>();
    /* run sql query using jdbc */
    for ( /* iterate over jdbc results */ ) {
        T item = c.newInstance();
        /* use reflection and set all of item’s fields from sql results */
        result.add(item);
    }
    return result;
}

Desde que Java apaga o parâmetro do tipo, tornando-o um java.lang.Object ou uma classe especificada como o genérico limite superior , é importante ter acesso ao objecto Class<T> dentro do método select. Uma vez que newInstance devolve um objecto do tipo <T>, o compilador pode efectuar a verificação do tipo, eliminando um molde.


1SUN Oracle publicou um bom artigo explicando tudo isso.
2 isto é diferente de implementações de genéricos sem apagamento de tipo, como um em. NET.
3Java Generics tutorial by Oracle.
 46
Author: dasblinkenlight, 2016-06-07 06:41:21

A resposta de dasblinkenlight já demonstrou uma das principais utilizações deste parâmetro. Há mais um aspecto que considero relevante: usando esse parâmetro, você pode restringir o tipo de classe que deseja passar em um determinado local. Por isso, por exemplo

Class<? extends Number> cls

Significa que cls pode ser qualquer classe que implemente a interface Number. Isso pode ajudar a capturar certos erros no tempo de compilação, e torna os requisitos de argumento de classe mais explícitos.

Talvez uma comparação com o case without generics is in order
// Java ≥5 with generics    // Java <5 style without generics
Class<? extends Foo> c;     Class c;
Foo t1 = c.newInstance();   Foo t1 = (Foo)c.newInstance();
Object obj;                 Object obj;
Foo t2 = c.cast(obj);       Foo t2 = (Foo)c.cast(obj);

Como podes ver, não ter T como argumento exigiria uma série de moldes explícitos, pois os métodos correspondentes teriam de retornar Object em vez de T. Se Foo em si é um argumento de tipo genérico, então todos os moldes seriam desligados, resultando em uma sequência de avisos de compilador. Você pode suprimi - los, mas a questão central permanece: o compilador não pode verificar a validade destes moldes a menos que você use corretamente o tipo argumento.

 7
Author: MvG, 2017-05-23 11:47:21

Em Java há um único metaclass: {[[0]}. Suas instâncias (somente uma por tipo existe) são usados para representar classes e interfaces, portanto, o T em Class<T> refere-se a tipo da classe ou interface que a instância atual do Class representa.

 1
Author: Óscar López, 2012-02-23 02:34:52

O uso de genéricos no tipo de classe é de topo definir o tipo de classe. Se eu tiver 'classe obj' o meu objeto obj pode ter apenas filhos de Charsequência. Este é um argumento opcional. Sou muitas vezes posto um "an"? para evitar avisos da IDE do Eclipse se eu não precisar de um tipo específico de classe.

 0
Author: Eldius, 2012-02-23 02:02:23