2010-12-15 18 views
8

En PL/SQL (o en muchos otros idiomas), puedo tener parámetros IN OUT o OUT, que se devuelven de un procedimiento. ¿Cómo puedo lograr algo similar en Java?Cómo crear parámetros IN OUT o OUT en Java

Sé que este truco:

public void method(String in, String[] inOut, String[] inOut2) { 
    inOut[0] = in; 
} 

donde el parámetro in representa un parámetro IN y el parámetro inOut puede contener un valor de retorno. La convención sería que String[] inOut es una matriz de inOut.length == 1.

Eso es un poco torpe.

EDITAR Evaluación de respuestas: Otros trucos incluyen: clases

  • titular/envoltura, pero no quiero introducir nuevos tipos, las devoluciones de llamada, etc.
  • valores de retorno: I' d como una solución general. Es decir. uno con varios parámetros IN OUT involucrados.
  • envoltorio para el parámetro IN OUT como valor de retorno: Esa es una opción viable, pero todavía no es tan agradable, ya que el envoltorio tendría que ser generada de alguna manera

¿alguien sabe una mejor manera de lograr esto por lo general? La razón por la que necesito una solución general es porque quiero generar código fuente conveniente de PL/SQL en un esquema de base de datos.

+1

* "valores de retorno: me gustaría una solución general, es decir, una con varios parámetros IN OUT involucrados" * Consulte mi respuesta. Varios params IN/OUT? Devuelve una instancia de objeto con propiedades para cada uno. Salvo eso, no, no hay nada mejor que el truco de la matriz. –

+1

Cuando comencé a aprender Java, después de muchos años de desarrollo de C/C++, también busqué una manera de pasar por referencia. Pero ahora, años después de eso, ya no recuerdo la última vez que quise hacer eso. El truco de matriz es menos elegante que otros enfoques citados en estas respuestas y comentarios. –

Respuesta

10

Mi pregunta sería: ¿Por qué methodno devuelve algo? En lugar de establecer un argumento de entrada/salida?

Pero suponiendo que absolutamente, positivamente debe tener un argumento de entrada/salida, que es una pregunta completamente diferente, entonces el truco de la matriz está bien. Alternativamente, no es menos torpe, pero la otra manera es pasar de una referencia de objeto:

public class Foo { 
    private String value; 

    public Foo(String v) { 
     this.value = v; 
    } 

    public String getValue() { 
     return this.value; 
    } 

    public void setValue(String v) { 
     this.value = v; 
    } 
} 

// .... 
public void method(String in, Foo inOut) { 
    inOut.setValue(in); 
} 

(. O, por supuesto, acaba de hacer pública value) Ver? Dije que no era menos torpe.

Pero preguntaría de nuevo: ¿No puede method devolver algo? Y si necesita devolver varias cosas, ¿no puede devolver una instancia de objeto con propiedades para esas cosas?

Fuera de tema: Esta es una de las áreas en las que realmente me gusta el enfoque C#. Uno de los argumentos en contra de los argumentos de entrada/salida es que no están claros en el momento en que está llamando a la función. Así que C# lo deja en claro, al especificar la palabra clave tanto en la declaración de la función como en la de al llamarlo. En la ausencia de ese tipo de ayuda sintáctica, evitaría "simular" argumentos de entrada/salida.

+0

El método no podrá devolver un solo valor, porque necesito una solución ** general **. He adaptado el ejemplo para mantener varios parámetros IN OUT. Pero tal vez devolver un objeto de resultado generado (manteniendo los parámetros IN OUT) en realidad podría ser una opción. +1 por eso. –

+0

Tiene razón sobre su comentario fuera del tema. En general, no necesito los parámetros IN OUT. Pero como estoy generando código fuente a partir del código PL/SQL real, no puedo prescindir de ...: -/ –

+0

En mi caso, necesito salir porque el método ya está devolviendo algo más. –

1

No hay manera directa. Otra técnica incluye:

  • pasando un objeto titular (un poco como la matriz de 1-aria)
  • usando, por ejemplo, Un AtomicInteger
  • Al pasar un objeto más útil desde un punto de vista comercial que pasa a ser mutable
  • una devolución de llamada a una interfaz personalizada para recibir el resultado

Si se piensa en ello, el truco matriz no es diferente a pasar una T * en C/C++

+0

Gracias por sus consejos. Pensé en esas cosas también, desafortunadamente, no funcionarán en mi caso ... –

3

Java copia todo lo que pase como argumento. Si pasa un método primitivo, dentro, tiene una copia de esa primitiva, y ninguna modificación afectará la variable real del método externo. Si pasa un objeto, pasa una copia de referencia, que realmente hace referencia al objeto original. Esta es la forma en que puede propagar modificaciones al contexto de algo que llamó al método, modificando el estado del objeto al que apunta la referencia. Vea más sobre esto: Does Java Pass by Value or by Reference?

+0

Gracias, sé que Java no pasa punteros reales sino "copias de referencia". Es por eso que se me ocurrió el truco de la matriz. Esa es una forma muy común de simular punteros en Java ... –

+0

+1 para explicar realmente la semántica de paso a paso que Java usa de una manera lógica. Hay muy pocas personas como usted en el mundo de hoy ... –

+0

@Lukas: * Sé que Java no pasa punteros reales sino "copias de referencia" * Lo cual es solo otro término para los punteros. ;-) –