¿Qué significa "Tipos incompatibles: el vacío no se puede convertir a ..."?
¿Qué significa el mensaje de compilación de Java?
"Incompatible types: void cannot be converted to ..."
significa y cómo lo soluciono. Algunos compiladores utilizan una redacción diferente; p.ej
"Type mismatch: cannot convert from void to ..."
o
"Incompatible types. Required: ... found: void"
o
"Incompatible types: Found void, required ..."
(Esto pretende ser una sesión de preguntas y respuestas canónicas para algunos mensajes de error de compilación muy específicos que involucran "void" y que tienden a confundir a los nuevos programadores de Java. No pretende ser un tutorial sobre los diferentes problemas de "conversión de tipos" que uno puede encontrar en Java.)
Respuesta rápida
El compilador le dice que su código está intentando utilizar el "resultado" de un método que no devuelve ningún resultado.
Solución:
Lea el javadoc del método que está intentando llamar (o el código fuente si no tiene javadocs).
A partir de los javadocs (o el código fuente), determine cómo debería usarse realmente el método.
Corrija su código para no utilizar el resultado (inexistente) o utilizar un método diferente. Alternativamente, si está llamando a uno de sus métodos, otra posible corrección podría ser cambiar el método para que devuelva un valor apropiado.
Ejemplo detallado
Considere este ejemplo:
public class Test {
private static void add(int a, int b) {
int res = a + b;
}
public static void main(String[] args) {
int sum = add(1, 1);
}
}
Cuando compilo esto usando javac
(Java 8), aparece el siguiente error de compilación.
$ javac Test.java
Test.java:7: error: incompatible types: void cannot be converted to int
int sum = add(1, 1);
^
1 error
El error de compilación en realidad nos dice algunas cosas:
El compilador ha detectado un problema en la posición indicada en la línea indicada del
main
método. La causa raíz del problema no está necesariamente en esa línea, pero ahí es donde el compilador descubrió que algo anda mal.Es un error de tipo, de ahí la frase "tipos incompatibles".
La incompatibilidad es de dos tipos:
void
yint
.El compilador piensa que el código requiere una conversión de
void
aint
... y eso no es posible.
Entonces ¿qué es este void
tipo?
Bueno, lo más probable es que hayas aprendido que Java admite dos tipos de tipos: tipos primitivos y tipos de referencia. El void
tipo no es ninguno de estos . Es el "tipo" que significa "no hay valor". (Si considera que los tipos son conjuntos de valores, entonces void
es el conjunto vacío).
El uso principal del void
tipo es en declaraciones de métodos. Mire la declaración del add
método anterior. Fíjate que hemos declarado add
con la firma:
private static void add(int a, int b)
Esa firma indica que el add
método toma dos int
métodos y devuelve void
. Eso significa que el método no devolverá nada.
Aún así... lo hemos llamado así:
int sum = add(1, 1);
Esto espera que la add
llamada devuelva un int
valor que le asignaremos sum
.
Esto es lo que realmente significa el mensaje de error "No se puede asignar un vacío a ..." . El compilador nos dice que el código está intentando utilizar el resultado de un método que se ha declarado que no devuelve ningún resultado. Eso no es posible. El lenguaje Java no permite "sacar un valor del aire" para utilizarlo.
Existen potencialmente dos formas de hacer que el error de compilación desaparezca:
Podríamos cambiar la declaración del método para que devuelva un valor. Por ejemplo:
private static int add(int a, int b) { int res = a + b; return res; }
Podríamos cambiar el sitio de llamada para que no intente utilizar el valor de retorno (inexistente). Por ejemplo:
add(1, 1);
En este ejemplo, cualquiera de los dos enfoques haría eso. Pero sólo un enfoque (el primero) hace que el código funcione según lo previsto .