> For the complete documentation index, see [llms.txt](https://educacion.gitbook.io/programacion/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://educacion.gitbook.io/programacion/ud7-poo-avanzada/clases-xenericas-xenerics.md).

# Clases Xenéricas (xenerics)

Java permite a utilización de clases xenéricas mediante a utilización do operador diamante (<>) e o uso de tipos xenéricos (T,Q,...).

Trátase dunha ferramenta que permite que unha clase traballe con diferentes tipos de datos sen comprometer a seguridade en tempo de compilación, engadindo moita flexibilidade na utilización da clase.

Un exemplo de clase xenérica sería o seguinte:

```java
public class ClaseXenerica<T>{

    private T atributo;

    public ClaseXenerica(T t){
        this.atributo = t;
    }

    public T getAtributo(){
        return this.atributo;
    }

    public void setAtributo(T t){
        this.atributo = t;
    }
    
    @Override
    public String toString() {
        return "ClaseXenerica{" +
                "atributo=" + atributo +
                '}';
    }

}
```

## Parámetro de tipo

O parámetro ou parámetros de tipo (T,Q,R,...) son os marcadores de posición de un tipo concreto que se indica na definición da clase dentro do operador diamante (<>).

* Un marcador de posición representa a un tipo de dato concreto: String, Integer, ou calquera clase das liberías de Java ou definida polo programador
* O marcador de posición permite manipular en cada caso obxectos de un tipo concreto, sen a necesidade de especificalo na definición
* As convencións de nombrado son as seguintes:
  * `T` → Type (tipo xenérico)
  * `U`, `S` , ...→ Tipos adicionais
  * `E` → Element (colecciones, moi común en listas)
  * `K` → Key, `V` → Value (Designa cada un dos elementos clave, valor de un mapa)
  * `N` → Number
  * `R` → Result (retornos)

Un exemplo de utilización da clase sería o seguinte:

```java
public class App {
    public static void main(String[] args) {
        ClaseXenerica<String> xen1 = new ClaseXenerica<String>("Esto é un String");
        Persona p = new Persona("Pepe",23); //Clase con nome, idade, constructor e toString()
        ClaseXenerica<Persona> xen2 = new ClaseXenerica<Persona>(p);
        System.out.println(xen1);
        System.out.println(xen2);
    }
}
```

<figure><img src="/files/9fAojTjZsPoXDip5BloY" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
O uso do operador diamante podese simplificar desde Java 7. Unicamente é necesario especificalo na definición, non e necesario facelo na parte de instanciación.

```java
ClaseXenerica<String> xen1 = new ClaseXenerica<>("Esto é un String");
ClaseXenerica<Persona> xen2 = new ClaseXenerica<>(p);
```

{% endhint %}

{% hint style="warning" %}
As comprobacións de clases xenericas **ClaseXenerica\<T> unicamente se realizan en tempo de compilación**. En tempo de **execución únicamente existe ClaseXenerica.**

**A nivel de execución, T comportase como un Object que** o bytecode castea automaticamente ao tipo concreto que se adopte en cada execución.
{% endhint %}

{% @mermaid/diagram content="graph LR
subgraph COMPILACION2\["En compilación"]
C1\["ClaseXenerica\<String><br/>xen1"]
C2\["ClaseXenerica\<Integer><br/>xen2"]
C3\["ClaseXenerica\<Persona><br/>xen3"]
end

```
subgraph EXECUCION2["En execución (type erasure)"]
    E1["ClaseXenerica<br/>xen1<br/>(atributo: Object = String)"]
    E2["ClaseXenerica<br/>xen2<br/>(atributo: Object = Integer)"]
    E3["ClaseXenerica<br/>xen3<br/>(atributo: Object = Persona)"]
end

C1 -->|"Type Erasure<br/>↓"| E1
C2 -->|"Type Erasure<br/>↓"| E2
C3 -->|"Type Erasure<br/>↓"| E3

E1 -.->|"Mesma clase!"| E2
E2 -.->|"Mesma clase!"| E3" %}
```

### Limitacións dos parámetros de tipo

* **Non se poden empregar con tipos básicos.** No seu lugar, poden empregarse os envoltorio correspondete a estes tipos (Integer, Double, Float, Boolean,...)
* **Non se poden empregar con Arrays para instanciación.** Devolve erro de compilación cando tentamos instancialo.

```java
public class ClaseXenerica<T>{

    private T atributo;
    private T[] lista;

    public ClaseXenerica(T t){
        this.atributo = t;
        //lista = new T[10]; Erro de compilación
    }
}
```

* **Non permite o uso de instanceof con tipos xenéricos (Type Erasure).** En tempo de execución, Java elimina os tipos xenéricos . Para realizar a comparación, sería necesario recuperar o elemento e verificar o seu tipo.

```java
if (xen1 instanceof ClaseXenerica<String>) //NON compila
  return true;
if (xen1 instanceof ClaseXenerica) //SI compila
  return true;
```

### Utilización de varios parámetros de tipos múltipes

E posible definir clases que traballen con mais de un marcador de posición:

```java
class Par<K, V> {
    private K clave;
    private V valor;

    public Par(K clave, V valor) {
        this.clave = clave;
        this.valor = valor;
    }

    public K getClave() {
        return clave;
    }

    public V getValor() {
        return valor;
    }
}
```

## Métodos con tipos xenéricos

É posible empregar marcadores de posición en métodos, especificando os marcadores dos parámetros previamente ao tipo de retorno do método

```java
public class Caixa {
    public static <T,Q> void mostrar(T dato, Q dato2){
        System.out.println("Pintando:" + dato + ", " + dato2);
    }
}
//No Main
 Caixa.mostrar("Pepe", Integer.valueOf(7));
```

No exemplo anterior

* \<T,Q> son os marcadores de posición dos parámetros do método
* void é o tipo de retorno do método

É posible tamén **combinar marcadores de posición na clase e nos métodos**, da seguinte forma:

```java
public class Contenedor <T>{

    private T atributo;

    public Contenedor(T t){
        this.atributo = t;
    }

    public <Q> void mostrar(Q q){
        System.out.println("Mostrando: " + this.atributo + ", " + q);
    }
}
//No main
Contenedor<String> cont = new Contenedor<>("Pepe");
cont.mostrar(Integer.valueOf(7));
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://educacion.gitbook.io/programacion/ud7-poo-avanzada/clases-xenericas-xenerics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
