java - ¿Qué significa "Tipos incompatibles: el vacío no se puede convertir a..."?
compiler-errors type-conversion (1)
Respuesta rápida
El compilador le dice que está tratando de usar el "resultado" de un método que no devuelve un resultado.
Solución:
-
Lea el javadoc para conocer el método al que está intentando llamar (o el código fuente si no tiene javadocs).
-
Del código fuente / javadocs se explica cómo se debe usar el método.
-
Corrija su código para no usar el resultado (inexistente) o para usar un método diferente. Alternativamente, cambie el método al que está llamando para devolver un valor.
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), obtengo 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 en el método
main
. La causa raíz del problema no está necesariamente en esa línea, pero ahí es donde el compilador ha descubierto que algo está mal. -
Es un error de tipo, de ahí la frase "tipos incompatibles".
-
La incompatibilidad involucra dos tipos:
void
eint
. -
El compilador
piensa
que el código requiere una conversión de
void
aint
... y eso no es posible.
Entonces, ¿qué es este tipo de
void
?
Bueno, lo más probable es que haya aprendido que Java admite dos tipos de tipos: tipos primitivos y tipos de referencia.
El tipo de
void
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 para el tipo
void
se usa en las declaraciones de métodos.
Mire la declaración del método
add
arriba.
Tenga en cuenta que hemos declarado
add
con la firma:
private static void add(int a, int b)
Esa firma indica que el método
add
toma dos métodos
int
y devuelve
void
.
Eso significa que el método no devolverá nada.
Sin embargo ... lo hemos llamado así:
int sum = add(1, 1);
Esto espera que la llamada a
add
devuelva un valor
int
que asignaremos a
sum
.
Esto es lo que realmente significa el mensaje de error "no se puede asignar el vacío ..." . El compilador nos dice que el código está tratando de usar el resultado de un método que se ha declarado que no devuelve ningún resultado. Eso no es posible. El lenguaje Java no le permite "sacar un valor del aire" para usar.
Hay 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 la llamada para que no intente usar el valor de retorno (inexistente). Por ejemplo:
add(1, 1);
En este ejemplo, cualquier enfoque haría eso. Pero solo un enfoque (el primero) hace que el código funcione según lo previsto .
Qué hace el mensaje de compilación de Java:
"Incompatible types: void cannot be converted to ..."
es decir, y cómo lo soluciono. Algunos compiladores usan una redacción diferente; p.ej
"Type mismatch: cannot convert from void to ..."
o
"Incompatible types. Required: ... Found: void
(Esto pretende ser un Q&A canónico para un mensaje de error de compilación muy específico que involucra "vacío" que confunde 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. )