Java genéricos vacíos/tipos vacíos

4 minutos de lectura

estoy implementando un ResponseHandler para el paquete apache HttpClient, así:

new ResponseHandler<int>() {
    public int handleResponse(...) {
        // ... code ...
        return 0;
    }
}

pero me gustaría para el handleResponse función para devolver nada, es decir void. es posible? Lo siguiente no compila, ya que void no es un tipo de Java válido:

new ResponseHandler<void>() {
        public void handleResponse(...) {
            // ... code ...
        }
}

Supongo que podría reemplazar void con Void devolver un Void objeto, pero eso no es realmente lo que quiero. Pregunta: ¿es posible organizar esta situación de devolución de llamada de tal manera que pueda devolver void de handleResponse?

avatar de usuario
ILMTitan

los Void type fue creado para esta situación exacta: para crear un método con un tipo de retorno genérico donde un subtipo puede ser “vacío”. Void fue diseñado de tal manera que no se pueden crear objetos de ese tipo. Así, un método de tipo Void siempre volveré null (o completo anormalmente), que es lo más cercano a nada que obtendrá. tienes que poner return null en el método, pero esto sólo debería ser un inconveniente menor.

En resumen: usa Void.

  • Arrgh: el dolor de los genéricos es que si, digamos, define un tipo de devolución de “Void”, debe poner “return (null);” la razón principal para declarar el tipo de devolución de void es para que no tenga que tener una declaración de devolución y pueda usar un método “void” existente 🙂 Parte del problema con Java Generics es la combinación de verificación de tipos en tiempo de ejecución con la necesidad de generación de código de tiempo de compilación y asistencia de “contabilidad”. Se necesitan “macros” y “plantillas” que ofrezcan comodidad al escribir código en el idioma lado.

    – peterk

    09/04/2013 a las 14:15


  • +1 Para aclarar, Void existe desde JDK1.1. Originalmente se creó para usar con Reflection, pero tiene una función similar en los genéricos.

    – John McCarthy

    16/08/2013 a las 16:30

  • @ILMTitan ¿Podría dar alguna referencia a la documentación sobre la declaración “return null” en los métodos que definieron para devolver Void?

    –Andriy Simonov

    25 de noviembre de 2016 a las 14:38

  • @andriy-simonov Métodos con un tipo de retorno de void no tiene que devolver un valor. Métodos con un tipo de retorno de Object o cualquier subclase, como Void tiene que devolver un valor (o no completar normalmente). El único valor que se le puede asignar Voidy por lo tanto regresó de un Void método, es null.

    – ILMTitan

    19/01/2018 a las 16:30

Generics solo maneja clases de objetos. Los tipos primitivos y vacíos no son compatibles con Generics y no puede usarlos como un tipo parametrizado. Tienes que usar Void en su lugar.

¿Puedes decir por qué no quieres usar Void?

  • simplemente preferiría no tener que incluir un return declaración en una función en la que no devuelvo nada, principalmente por limpieza.

    – Travis Webb

    06/04/2011 a las 17:00

  • Podrías crear un envoltorio abstracto que te llame void método y devoluciones null para ocultar esta fealdad.

    – Peter Lawrey

    06/04/2011 a las 18:00

  • +1 por recordarme que “cualquier problema en informática se puede resolver agregando una capa de direccionamiento indirecto”

    – Travis Webb

    6 de abril de 2011 a las 18:05


  • @TravisWebb Mirando su necesidad específica, simplemente no use genéricos y regrese Object escriba si funcionará

    – Chaitanya

    19 de febrero de 2020 a las 11:52


avatar de usuario
ken chu

cuando necesitas volver java.lang.Voidsolo regresa null.

avatar de usuario
marca-cs

No puedes tener primitivos en genéricos para que int es en realidad un Integer. El objeto Void es análogo a la palabra clave void para genéricos.

avatar de usuario
Adrián Smith

Por desgracia, no es posible. Puede configurar el código para volver Void como dices, sin embargo, nunca puedes instanciar un Void por lo que en realidad no puede escribir una función que se ajuste a esta especificación.

Piense en ello como: la función genérica dice “esta función devuelve algo, de tipo X”, y puede especificar X pero no puede cambiar la oración a “esta función no devuelve nada”. (No estoy seguro si estoy de acuerdo con esta semántica, pero así es como son).

En este caso, lo que siempre hago es hacer que la función devuelva el tipo Objecty de hecho siempre regresa null.

  • Porque con un tipo de retorno de Objeto, el compilador no puede garantizar que solo se devuelva nulo. Ampliando la respuesta de Thomas, pruebe estos: static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; }

    – Nathan Niesen

    28 de julio de 2017 a las 17:59

avatar de usuario
JTHouseCat

Esta implementación de java.lang.Void en Java habla por sí misma. Además, escribí un artículo que relaciona esto con los genéricos. Me tomó un poco de pensamiento antes de empezar a entender esto: http://www.siteconsortium.com/h/D00006.php. TIPO de aviso = Class.getPrimitiveClass(“void”);

paquete java.lang;

public final class Void {

    public static final Class<Void> TYPE = Class.getPrimitiveClass("void");

    private Void() {}
}

  • Porque con un tipo de retorno de Objeto, el compilador no puede garantizar que solo se devuelva nulo. Ampliando la respuesta de Thomas, pruebe estos: static Void v() { return null; } static Void n() { return "NotAllowed"; } static Object o() { return "Allowed"; }

    – Nathan Niesen

    28 de julio de 2017 a las 17:59

¿Ha sido útil esta solución?