valores sintaxis sentencia retornar retornan retorna que metodos metodo ejemplos como clases arreglo java reference arguments return-value

sintaxis - ¿Deberían usarse los argumentos del método Java para devolver múltiples valores?



sintaxis de un metodo en java (9)

Ciertamente hay métodos que modifican un objeto pasado como parámetro ( vea java.io.Reader.read (byte [] buffer) como ejemplo, pero no he visto parámetros utilizados como alternativa para un valor de retorno, especialmente con múltiples parámetros. Puede que técnicamente funcione, pero no es estándar.

Dado que los argumentos enviados a un método en Java apuntan a las estructuras de datos originales en el método del llamador, ¿pretendían sus diseñadores que se usaran para devolver múltiples valores, como es la norma en otros idiomas como C?

¿O es esto un mal uso peligroso de la propiedad general de Java de que las variables son punteros?


Desearía que hubiera una clase Pair<E,F> en JDK, principalmente por esta razón. Hay un Map<K,V>.Entry , pero crear una instancia siempre fue un gran dolor.

Ahora uso com.google.common.collect.Maps.immutableEntry cuando necesito un Pair


En general, lo que dijo Eddie, pero yo agregaría uno más:

  • Mutar uno de los objetos entrantes y devolver un código de estado. En general, esto solo debe usarse para argumentos que son explícitamente buffers, como Reader.read (char [] cbuf).

En general, no se considera una práctica muy buena, pero hay casos muy ocasionales en el JDK donde se hace esto. Mire el parámetro ''biasRet'' de View.getNextVisualPositionFrom () y los métodos relacionados, por ejemplo: en realidad es una matriz unidimensional que se llena con un "valor de retorno extra".

Entonces, ¿por qué hacer esto? Bueno, solo para evitar que tenga que crear una definición de clase adicional para el "valor de retorno extra ocasional". Es desordenado, poco elegante, mal diseñado, no orientado a objetos, bla bla. Y todos lo hemos hecho de vez en cuando ...


En mi opinión, si estamos hablando de un método público, debe crear una clase separada que represente un valor de retorno. Cuando tienes una clase separada:

  • sirve como una abstracción (es decir, una clase Point lugar de una matriz de dos largos)
  • cada campo tiene un nombre
  • se puede hacer inmutable
  • hace que la evolución de la API sea mucho más fácil (es decir, qué hay de devolver 3 en lugar de 2 valores, cambiar el tipo de algún campo, etc.)

Siempre optaría por devolver una nueva instancia, en lugar de modificar realmente un valor pasado. Me parece mucho más claro y favorece la inmutabilidad.

Por otro lado, si se trata de un método interno, supongo que se puede usar cualquiera de los siguientes:

  • una matriz ( new Object[] { "str", longValue } )
  • una lista ( Arrays.asList(...) devuelve una lista inmutable)
  • clase par / tupla, como this
  • Clase interna estática, con campos públicos.

Aún así, preferiría la última opción, equipada con un constructor adecuado. Esto es especialmente cierto si te encuentras devolviendo la misma tupla desde más de un lugar.


Hace mucho tiempo tuve una conversación con Ken Arnold (un miembro del equipo de Java), probablemente habría sido en la primera conferencia de Java One, así que en 1996. Dijo que estaban pensando en agregar varios valores de retorno para que pudiera escribe algo como:

x, y = foo();

La forma recomendada de hacerlo en ese entonces y ahora es crear una clase que tenga varios miembros de datos y devolverla.

Basado en eso, y en otros comentarios hechos por personas que trabajaron en Java, yo diría que la intención es / es que devuelvas una instancia de una clase en lugar de modificar los argumentos que se pasaron.

Esta es una práctica común (como lo es el deseo de los programadores de C de modificar los argumentos ... eventualmente ven la forma de hacerlo de Java por lo general. Solo piense en esto como en devolver una estructura. :-)

(Edición basada en el siguiente comentario)

Estoy leyendo un archivo y generando dos matrices, de tipo String e int desde él, seleccionando un elemento para ambas de cada línea. Quiero devolverlos a cualquier función que lo llame a un archivo para dividirlo de esta manera.

Creo que, si te estoy entendiendo correctamente, probablemente haría algo así:

// could go with the Pair idea from another post, but I personally don''t like that way class Line { // would use appropriate names private final int intVal; private final String stringVal; public Line(final int iVal, final String sVal) { intVal = iVal; stringVal = sVal; } public int getIntVal() { return (intVal); } public String getStringVal() { return (stringVal); } // equals/hashCode/etc... as appropriate }

y luego tener su método como este:

public void foo(final File file, final List<Line> lines) { // add to the List. }

y luego llámalo así:

{ final List<Line> lines; lines = new ArrayList<Line>(); foo(file, lines); }


Realmente no puede devolver múltiples valores, pero puede pasar objetos a un método y hacer que el método mute esos valores. Eso es perfectamente legal. Tenga en cuenta que no puede pasar un objeto y hacer que el objeto se convierta en un objeto diferente. Es decir:

private void myFunc(Object a) { a = new Object(); }

resultará en un cambio temporal y local del valor de a , pero esto no cambiará el valor de la persona que llama, por ejemplo, de:

Object test = new Object(); myFunc(test);

Después de que regrese myFunc, tendrá el Objeto antiguo y no el nuevo.

Legal (y muchas veces desanimado) es algo como esto:

private void changeDate(final Date date) { date.setTime(1234567890L); }

Elegí la Date por una razón. Esta es una clase en la que la gente está de acuerdo en que nunca debería haber sido mutable. El método anterior cambiará el valor interno de cualquier objeto Date que le pase. Este tipo de código es legal cuando está muy claro que el método mutará o configurará o modificará lo que se está pasando.

NOTA: Generalmente, se dice que un método debe hacer una de estas cosas:

  • Devuelve void y muta sus objetos entrantes (como Collections.sort() ), o
  • Devuelva algunos cálculos y no mute los objetos entrantes en absoluto (como Collections.min() ), o
  • Devuelve una "vista" del objeto entrante pero no modifica el objeto entrante (como Collections.checkedList() o Collections.singleton() )
  • Mutar un objeto entrante y devolverlo ( Collections no tiene un ejemplo, pero StringBuilder.append() es un buen ejemplo).

Los métodos que mutan los objetos entrantes y devuelven un valor de retorno separado a menudo hacen demasiadas cosas.


Tuve un objeto Resultado que cae en cascada a través de una serie de métodos de validación de vacíos como un parámetro de método. Cada uno de estos métodos de validación de vacíos mutaría el objeto de parámetro de resultado para agregar el resultado de la validación.

Pero esto es imposible de probar porque ahora no puedo anular el método void para devolver un valor de código auxiliar para la validación en el objeto Result.

Entonces, desde una perspectiva de prueba, parece que uno debería favorecer la devolución de un objeto en lugar de mutar un parámetro de método.


Vea este RFE lanzado en 1999:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4222792

No creo que la intención fuera permitirlo nunca en el lenguaje Java, si necesita devolver varios valores, necesita encapsularlos en un objeto.

Usando lenguajes como Scala, sin embargo puedes devolver tuplas, ver:

http://www.artima.com/scalazine/articles/steps.html

También puede usar Genéricos en Java para devolver un par de objetos, pero eso es todo AFAIK.

EDITAR: Tuplas

Sólo para agregar un poco más sobre esto. Anteriormente he implementado un par en proyectos debido a la falta dentro del JDK. El enlace a mi implementación está aquí:

http://pbin.oogly.co.uk/listings/viewlistingdetail/5003504425055b47d857490ff73ab9

Tenga en cuenta que no hay un código hash o igual en esto, que probablemente debería agregarse.

También me encontré con esto al hacer una investigación sobre estas preguntas que proporciona funcionalidad de tupla:

this

Te permite crear un par incluyendo otros tipos de tuplas.