¿Tiene / por qué Java necesita tener voidmétodos? Referencia :
Cualquier método declarado vacío no devuelve un valor.
Hasta donde puedo pensar, cada uso de voidsería mejor al devolver un indicador de estado, el objeto que se invoca, o null.
Esto haría que cada llamada sea una declaración asignable y facilitaría los patrones de creación y el encadenamiento de métodos. Los métodos que solo se invocan por sus efectos generalmente devolverían un tipo booleano o genérico Successo arrojarían una excepción en caso de falla.
java
programming-languages
return-type
marisbest2
fuente
fuente

Respuestas:
Debido a que existe una diferencia entre "Esta función puede tener éxito o fallar y es lo suficientemente consciente de sí misma como para poder notar la diferencia" y "No hay comentarios sobre el efecto de esta función". Sin esto
void, verificaría infinitamente los códigos de éxito y creería que está escribiendo un software robusto, cuando en realidad no está haciendo nada por el estilo.fuente
voidno dice nada sobre si el método o la función es lo suficientemente consciente de sí mismo como para lanzarlo según corresponda.voidtipo, y Java fue diseñado para seguir muchas de las convenciones de la familia de lenguaje C.Successtipo genérico " de todos modos? De hecho, los valores de retorno para indicar el éxito son incluso menos importantes en Java que en C, porque Java tiene excepciones para indicar fallas y C no.fuente
Voidtipo de Java actúa como un tipo de Unidad (por ejemplo, para genéricos), aunque lamentablemente, es diferente devoid(nota al margen: un gatito adorable muere cada vez que inventa un nuevo tipo para arreglar el tipo que estropeó en la versión anterior). Si alguien no está familiarizado con los tipos de unidades, esta es una introducción decente: en.wikipedia.org/wiki/Unit_typenull(de hecho, esta es la única opción), pero nulo es algo especial, cualquier valor de tipo de referencia en Java puede ser nulo (este es otro error en el diseño del lenguaje). Y, como dije antes, si está utilizando elVoidtipo de retorno en lugar devoidmark, el compilador de Java no es su amigo.null. El hecho de quenullsea un miembro de la mayoría de los tipos es irrelevante para saber siVoides un tipo de unidad.La razón original por la cual el lenguaje tiene un
voidtipo es porque, como enC, los creadores del lenguaje no querían complicar innecesariamente la sintaxis del lenguaje con procedimientos y funciones como lo hizo Pascal.Esa fue la razón original.
Tus sugerencias:
Eso es un no-no. No utilizamos banderas de estado. Si algo sale mal, lo informamos a través de excepciones.
El estilo fluido de las invocaciones es un desarrollo reciente. Muchos de los programadores que usan muy bien el fluido hoy y ponen los ojos en blanco si alguna vez tienen que usar una interfaz que no lo admite, ni siquiera nacieron cuando se creó Java.
Eso lo obligaría a declarar que un método devuelve algo, cuando de hecho no devuelve nada, por lo que sería muy confuso para alguien que está mirando una interfaz tratando de descubrir qué hace. La gente inevitablemente inventaría alguna clase inútil que significa "sin valor de retorno" para que todas las funciones que no tienen nada que devolver puedan devolver una referencia nula a dicha clase. Eso sería torpe. Afortunadamente, hay una solución para esto, se llama
void. Y esa es la respuesta a tu pregunta.fuente
int, por lo que se agregaba una palabra clave después de K&R para indicar 'tipo de no retorno'.Algunos métodos, como
System.out.printlnno devuelve nada útil, pero se llama únicamente por este efecto secundario.voides un indicador útil para el compilador y para el lector de código de que no se devuelve ningún valor útil.Devolver en
nulllugar devoidsignifica que solo obtendríaNullPointerExceptionel momento en que use este valor para cualquier cosa. Por lo tanto, intercambia un error de tiempo de compilación por un error de tiempo de ejecución que es mucho peor. Además, tendría que definir el tipo de retorno comoObject, lo que sería engañoso y confuso. (Y el encadenamiento aún no funcionaría).Los códigos de estado generalmente se usan para indicar condiciones de error, pero Java tiene excepciones para este propósito.
thisNo es posible regresar de métodos estáticos.Devolver un
Successobjeto genérico no tendría ningún propósito útil.fuente
Una de las razones es que puede ser engañoso para volver jamás otra que, digamos nada,
null. Ejemplo:¿Qué debería
Arrays.sort(a)volver?Si argumenta que
adebe devolverse para poder encadenar la llamada (que parece ser su respuesta a juzgar por su pregunta), entonces ya no está claro si el valor devuelto es una copia del objeto original o el objeto original en sí . Ambos son posibles. Y sí, podría incluirlo en la documentación, pero es lo suficientemente ambiguo como para no crear la ambigüedad en primer lugar.Por otro lado, si usted argumenta que
nulldebería devolverse, eso plantea la pregunta de qué información posiblemente el valor de retorno está proporcionando al llamante, y por qué el programador debería verse obligado a escribirreturn nullcuando no transmite información.Y si devuelve algo totalmente absurdo (como la longitud de
a), entonces hace que usar ese valor de retorno sea realmente confuso, ¡solo piense cuánto más confuso es decir enint len = Arrays.sort(a)lugar deint len = A.length!fuente
return null;: la JVM también podría exigir que si el control se cae al final de una función por otro medio que no sea explícitoreturno unathrowdeclaración,nullse devuelve implícitamente a la persona que llama. IIRC C hace eso, excepto que el valor de retorno no está definido en ese caso (será el valor que esté en la ubicación utilizada para el valor de retorno en ese momento).returndeclaración. En cambio, aparece un error del compilador que le informa sobre su error. Insertar un implícitoreturn null;sería mejor que el "comportamiento indefinido", pero no mucho. Eso sería útil solo cuando el tipo de retorno no tiene significado, pero ¿de dónde saca el compilador la conclusión de que el valor de retorno no tiene significado, cuando no lo esvoid?returnrealmente no agrega ningún valor ...", bueno, como se dijo, no hay ningún indicador para el compilador de que una devolución no agregaría ningún valor, si no hay ningúnvoidtipo. En realidad es lo contrario, la primera suposición es que un método que declara un tipo de retorno quierereturnalgo útil de ese tipo. Y aún no hablamos sobre los tipos primitivos, que no tienen unnullvalor, por lo tanto, cualquier valor predeterminado inyectado por el compilador entraría en conflicto con el rango de valores de retorno potencialmente útiles.Devolver un valor
booleanque siempre es igual altrueque sugiere, no solo no tiene sentido (el valor de retorno no contiene información), sino que en realidad sería engañoso. La mayoría de las veces, es mejor usar tipos de retorno que solo contengan tanta información como esté realmente disponible; es por eso que en Java tienebooleanparatrue/ enfalselugar de devolver unintcon 4 mil millones de valores posibles. Del mismo modo, devolver abooleancon dos valores posibles donde solo hay un valor posible ("éxito genérico"), sería engañoso.También agregaría una sobrecarga de rendimiento innecesaria.
Si un método se usa solo por su efecto secundario, no hay nada que devolver, y el tipo de retorno
voidrefleja exactamente eso. Los posibles errores raros se pueden señalar mediante excepciones.Una cosa que podría mejorarse sería crear
voidun tipo real, como el de ScalaUnit. Esto resolvería algunos problemas, como el manejo de genéricos.fuente
List.addsiempre regresatrue, pero eso es por ser compatible con el contrato más amplio deCollection.add, por lo queSet.addpuede regresartrueofalse.Java es un lenguaje relativamente antiguo. Y en 1995 (cuando se creó) y poco después, los programadores estaban muy preocupados por la cantidad de tiempo que un proceso tomó el control del procesador, así como el consumo de memoria. Devolver el vacío eliminaría algunos ciclos de reloj y un poco de consumo de memoria de una llamada a función porque no tendría que poner el valor de retorno en la pila, y no tendría que eliminarlo posteriormente.
El código eficiente no le devuelve algo que nunca usaría y, por lo tanto, anular algo que tiene un valor de retorno sin sentido es una práctica mucho mejor en lugar de devolver un valor de éxito.
fuente
He leído argumentos que sugieren que la segunda opción (retorno
this) debería ser el enfoque en lugar devoid. Esta es una idea bastante buena, pero el enfoque de estilo de constructor no era popular en el momento en que se creó Java. Si era tan popular en ese momento como lo es ahora, ese podría haber sido el enfoque adoptado. Volvernulles una muy mala idea de la OMI. Desearía quenullni siquiera estuviera en el idioma.El problema ahora es que si un método devuelve una instancia de su propio tipo, no está claro si es un objeto nuevo o el mismo. A menudo no importa (o no debería), pero otras veces sí importa. Supongo que el lenguaje podría cambiarse para devolver implícitamente los
thismétodos nulos. El único problema que puedo pensar con eso en este momento es que si el método fue cambiado más tarde para devolver un nuevo objeto del mismo tipo, no habría advertencias de compilación, pero tal vez eso no sea gran cosa. El sistema de tipos actual no se preocupa por estos tipos de cambios ahora. La forma en que esto interactúa con la herencia / interfaces necesitaría cierta consideración, pero permitiría que las API antiguas sin un estilo de generador se llamaran fácilmente como si lo hicieran.fuente
nullno fuera parte del lenguaje, las personas estarían usando todo tipo de valores centinela que significan "ignore este argumento / valor de retorno, no contiene ningún valor sensible". El problema connullno es la cosa en sí, solo que tiende a usarse incorrectamente. Apostaría a que este problema sólo sería exagerado si el estandarizadanullsería reemplazado con una gran variedad de soluciones a medida, donde cada aplicación se comportaría de manera diferente en silencio como ignorar el uso, o lanzar excepciones especiales en lugar de una excepción de puntero nulo standart, etcnulles un tipo opcional adecuado (como,Maybeen Haskell). El problema con los valores nulos en Java es que no hay una forma sensata de decidir de inmediato si un valor es anulable en la práctica o no. Esto lleva a ambos: programación innecesariamente defensiva (verificar nulos donde no tiene sentido, lo que aumenta el porcentaje de popó en el código) y NPE accidentales en producción (si olvidó verificar dónde era necesario). Sí, se resuelve parcialmente mediante anotaciones, pero son opcionales, no siempre se verifican, etc. Por lo tanto, no lo salvarán en los límites con código de terceros.nullfunciona bien para esto (fine = simple), pero los valores opcionales estandarizados con semántica sólida son definitivamente otra buena opción (fine = safe).Otro aspecto:
Java es un lenguaje estático con características bastante estrictas. Esto significa que muchas cosas que serían bastante abiertas o dinámicas en otros idiomas (c / f Ruby, Lisp, etc.) están estrictamente determinadas.
Esta es una decisión general de diseño. El "por qué" es difícil de responder (bueno, ¡porque los diseñadores del lenguaje pensaron que sería bueno!). El "para qué" es bastante claro: permite que el compilador detecte muchos errores, que generalmente es una característica bastante buena para cualquier idioma. En segundo lugar, hace que sea relativamente fácil razonar sobre el idioma. Por ejemplo, es relativamente fácil crear pruebas formales de corrección en (subconjuntos de) el lenguaje Java; en comparación, eso sería prácticamente imposible en un lenguaje dinámico como Ruby et al.
Este pensamiento impregna el lenguaje, por ejemplo, la declaración forzada de posibles excepciones que puede arrojar un método, el tipo separado de
interfacevs.classpara evitar una herencia múltiple ambigua, y así sucesivamente. Por lo que es (un lenguaje del mundo real imperativo estático OOP con un fuerte enfoque en el manejo de errores en tiempo de compilación), esas cosas son en realidad bastante elegantes y poderosas. Se acercan más a los lenguajes teóricos (científicos) que están hechos a propósito solo para explorar algunos de estos problemas que cualquier otro lenguaje del mundo real antes (en ese momento, eso sí).Entonces. Tener un
voidtipo estricto es un mensaje claro: este método no devuelve nada, punto. Es lo que es. Reemplazarlo por la aplicación para que siempre devuelva algo conduciría a un comportamiento mucho más dinámico (como en Ruby, donde cada def tiene un valor de retorno explícito o implícito, siempre), lo que sería malo para la demostrabilidad y el razonamiento; o para una hinchazón masiva usando algún otro mecanismo aquí.(Y NB, Ruby (por ejemplo) maneja esto de manera diferente, y su solución sigue siendo exactamente tan aceptable como la de Java, porque tiene una filosofía completamente diferente. Por ejemplo, arroja completamente la probabilidad y la razonabilidad por completo mientras pone un gran enfoque en extremadamente alta expresividad del lenguaje.)
fuente