---
title: Inferencia tipos Java: El operador diamante
url: https://jarroba.com/inferencia-tipos-java-operador-diamante/
author: Dionisio Cortes
date: 2017-05-06
modified: 2026-10-23
language: es
license: CC BY-NC-SA 3.0 (https://creativecommons.org/licenses/by-nc-sa/3.0/) — attribution: "Inferencia tipos Java: El operador diamante", Dionisio Cortes, jarroba.com
categories: Lenguajes de Programación
tags: genericos, java, operador diamante
repository: https://github.com/dionisioC/diamondOperator
---

# Inferencia tipos Java: El operador diamante

> El operador diamante de Java, permite quitarnos cierta verbosidad a la hora de escribir nuestro código

El proyecto de este post los puedes descargar pulsando [AQUI](https://github.com/dionisioC/diamondOperator).

 

## Intro

 

El operador diamante es básicamente azúcar sintáctico (syntactic sugar) de Java, que nos va a permitir quitarnos cierta verbosidad a la hora de escribir nuestro código. Esta característica fue incluida en Java 7, por lo que solo podréis usarla en versiones superiores a Java 7.

 

### Ya estaba disponible en métodos

 

Esta sintaxis ya estaba disponible en los métodos, lo que nos aporta Java 7 es traernos esta tecnología a los constructores.

 

Si nosotros declarábamos en una clase GenericMehodClass

 

```java

public class GenericMehodClass {

    public <T> void printElement(T element){
        System.out.println(element);
    }

}
```

 

Podemos invocarlo

 

```java

GenericMehodClass genericMehodClass = new GenericMehodClass();
genericMehodClass.<String>printElement("Hola");
genericMehodClass.<Integer>printElement(5);
```

 

Pero el compilador es lo suficientemente inteligente como para saber que si lo que le pasamos es un string, no tenemos que repetírselo, por lo que podemos simplemente decirle:

 

```java

genericMehodClass.printElement("Hola");
genericMehodClass.printElement(5);
```

 

Resultado

 

```bash

Hola 
5 
Hola 
5
```

 

### Operador diamante

 

El operador diamante es una mejora en la inferencia de tipos en genéricos, dejando que el compilador sea quien determine el tipo de la clase genérica y no el programador, con el consiguiente ahorro de esfuerzo y tiempo que ello suponía. Además como mucha gente pensaba, no aportaba mucho tener a la derecha y a la izquierda duplicados los tipos.

 

Con Java 6

 

```java

//Java 6 style
List<String> java6List = new ArrayList<String>();
```

 

Con java 7

 

```java

//Java 7 style
List<String> java7List = new ArrayList<>();
```

 

De esta manera queda menos verboso, el compilador sabe que java7List va a ser de tipo String al estar declarado en la parte izquierda. Los dos ejemplos hacen exactamente lo mismo.

 

### Declaración de clases genéricas

 

No solo podemos usar las clases genéricas como List, Map, Set, etc. Podemos crearnos las nuestras propias, además complicando todo lo que queramos. En el siguiente ejemplo vamos a ver que nos podemos declarar una clase genérica que sea de tipo U, conteniendo una lista de tipo U y con un constructor de tipo T

 

```java

import java.util.ArrayList;
import java.util.List;

public class GenericClass <U> {

    List<U> list = new ArrayList<>();

    <T> GenericClass(T t) throws NoSuchFieldException {
        System.out.println("T: " + t.getClass().getSimpleName());
    }

    public void add(U element){
        list.add(element);
        System.out.println("U: " + list.get(0).getClass().getSimpleName());
    }

}
```

 

Como vemos la podemos instanciar con el operador diamante:

 

```java

GenericClass<String> genericClass1 = new GenericClass<>(5);
genericClass1.add("Hola");
```

 

Si lo ejecutamos nos va a decir:

 
- T: Integer
- U: String

 

Ya que hemos dicho que el constructor va a ser Integer, pero la clase String. Sin embargo:

 

```java

GenericClass genericClass2 = new GenericClass("Hola");
genericClass2.add(5);
```

 

Nos dice que el constructor es String, pero la clase Integer.

 
- T: String
- U: Integer

 

El ejemplo es rebuscado, es solo para dar una visión de lo que se puede hacer con genéricos en cuanto a inferencia de tipos.

 

### Algunas restricciones

 

Para poder beneficiarnos de la sintaxis, es obligatorio poner el operador diamante (omitir el tipo a la derecha) siempre que el compilador pueda inferir los tipos del contexto. Recordemos que esto es un avance del compilador que ahora es más “listo”, pero no adivino.

 

Si volvemos al ejemplo anterior:

 

Con Java 6

 

```java

//Java 6 style
List<String> java6List = new ArrayList<String>();
```

 

Con java 7

 

```java

//Java 7 style
List<String> java7List = new ArrayList<>();
```

 

Esa sería la sintaxis correcta, si hacemos

 

```java

List<String> java7NonDiamondList = new ArrayList();
```

 

Nos va a dar un warning

 

```java

Warning:(26, 43) java: unchecked conversion  required: java.util.List  found: java.util.ArrayList
```

 

Ya que new ArrayList() hace referencia al tipo raw de ArrayList y no a su tipo genérico.

 

Tener la flexibilidad de tener tipos genéricos, no hace que perdamos el tipado fuerte de Java, por ejemplo, en la lista podemos hacer

 

```java

java7List.add("Hola");
```

 

Pero no podemos hacer (en la misma lista)

 

```java

java7List.add(5);
```

 

Pues nos da el siguiente error:

 

```java

add (java.lang.String) in List cannot be applied to (int)
```

 

### Bibliografía

 

- [Generic Methods (The Java Tutorials)](https://docs.oracle.com/javase/tutorial/java/generics/genMethods.html)
- [Lesson: Generics (Updated) (The Java Tutorials)](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
