Envio y recepcuion de parametros entre metodos...

Buenas tardes,

Soy nuevo en el desarrollo de java y tengo una duda con respecto al paso de parámetros entre metodos y es el siguiente;

1.- Tengo un metodo 1 el cual debe enviar una variable “A” a un metodo 2.
2.- El metodo 2 debe procesar el parámetro “A” y devolver al metodo 1 el parametro B

De verdad estoy un poco confundido con esto de pasar y recibir variables por lo cual les agradeceria si observación al respecto.

Saludos.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Referencias

Recuerda que en Java tienes tipos primitivos y tienes objetos. Los tipos primitivos se pasan siempre por valor y los objetos se pasan siempre por referencia.

si en una clase tienes dos métodos, uno llama al otro de esta manera:

public void m1() {
  int x = 1;
  obj.setNombre("Pedro");
  String res = m2(x, obj);
  System.out.println(x);
  System.out.println(obj.getNombre());
}

public String m2(int a, Objeto b) {
  a = 5;
  b.setNombre("Juan");
  return "ok";
}

El método m1 imprimirá 1 y luego imprimirá "Juan". Esto porque el parámetro tipo int se pasa por valor. Esto significa que la variable x dentro de m1 mantiene su valor; se pasa el contenido de la variable (el 1) como parámetro a m2, que ahora tiene ese 1 en el parámetro a. Al asignarle 5 a la variable a, solamente se afecta dentro de m2. La variable x en m1 sigue siendo 1.

En cambio, el objeto "obj" de m1 se pasa por referencia a m2, es decir, son como apuntadores al mismo objeto realmente, no se hace una copia ni nada. Por eso el cambio que se hace al nombre del objeto, se ve reflejado después en m2.

Imagen de OscarRyz

@ezamudio: Más o menos.

@ezamudio: Más o menos. En Java, todo se pasa por valor, incluyendo los objetos. Lo que sucede es que el valor que se pasa con los objetos es una copia del valor de la referencia. Pero Java mismo no soporta el "pase por referencia".

En un lenguaje donde pasas la variable por referencia ( como C++, o VB por ejemplo ) un cambio en la variable pasada, afecta el original.

Por ejemplo, considerando el siguiente código.

// Una clase, X, que tiene una variable.
// mostrada aquí como public nomás para simplificar el código.
class SomeClass {
    public int intVariable = 0;
}
....
void someMethod(){
     SomeClass object = new SomeClass();
     object.intVariable = 42; // set it to something to make it different
     change( object );
     assert  object.intVariable == 42;
}
void change( SomeClass objectReference ) {
      objectReference = new SomeClass();
      objectReference.intVariable = 1024;
}

En un lenguaje donde los objetos se pasan por referencia, la invocación del método change haría que la referencia del objeto cambiara y como resultado, la variable final no tendría como valor el 42, sino el 1024 asignado al final.

Como en Java las referencias se pasan también por valor, la referencia llamada "object" no cambia, cuando es pasada por el método "change", y conserva el 42 al final del ejemplo.

Pero como lo que nos es pasado es una copia de la referencia, podemos modificar el atributo del objeto al que ese objeto "apunta"

Si el código fuera:

void changeV2( SomeClass objectReference ) {
      objectReference.intVariable = 256;
}

Entonces el valor final, no sería 42, sino 256.

Links:

http://stackoverflow.com/questions/40480/is-java-pass-by-reference
http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html ( al final donde dice: "Passing Reference Data Type Arguments" )

Imagen de OscarRyz

@LUIS231268

Respecto a tu duda, no dices que es lo que llevas o que es lo que si entiendes y lo que no. Así que ahi te va algo que quizá te parezca muy básico ( o quizá no, no lo sé )

Si tienes un método 1 que le envía una variable A a un método 2, en programación orientada a objectos esto se llama como "mandarle un mensaje" y la variable es el "argumento", el metodo 2 debe de definir un parametro, para recibir ese argumento.

Entonces:

public void metodoUno(){
     int variableA = 10;
     // aquí se manda un mensaje: metodoDos con el argumento "variableA"
      // y el resultado del procesamiento es almacenado en la variableB
    int variableB = metodoDos( variableA );
}
public void metodoDos( int  a ) {
     // el parametro que recibe se llama a
     // el procesamiento puede ser de cualquier cosa
     // por ejemplo dividirlo entre 2.
    return a / 2; // si a es 10 entonces regresa 5
}

Como te decía antes, esto puede ser muy básico, pero es el inicio. El metodoUno, llamó al metodoDos pasando la variableA ( que en el métodoDos se define como el parametro a ) , hace con el un procesamiento ( que este caso fue dividirlo entre dos ) y lo regresa y se le asigna a la variable b

Imagen de cyberserver

YA esta

mmmmm, pues no estoy muy de acuerdo en lo que dicen (Foros,Blogs,etc..) que en Java no Existen paso de parametros por Referencia.

Estoy de acuerdo en lo que dice @Ezamudio
Recuerda que en Java tienes tipos primitivos y tienes objetos. Los tipos primitivos se pasan siempre por valor y los objetos se pasan siempre por referencia.

Primero definiremos los terminos

Paso por valor :significa que cuando un argumento se pasa a una función, la función recibe una copia del valor original. Por lo tanto, si la función modifica el parámetro, sólo la copia cambia y el valor original permanece intacto.

Paso por referencia :significa que cuando un argumento se pasa a una función, la función recibe la dirección de memoria del valor original, no la copia del valor. Por lo tanto, si la función modifica el parámetro, el valor original en el código que llamó a la función cambia.

Y como yo veo, en el ejemplo que dio ezamudio se cumple la definicion de paso por Referencia.
Se da como parametro un Objeto, Objeto que despues utiliza el metodo Setter para cambiar el Valor de la Variable "Nombre", la misma Variable "Nombre" que estaba antes de haberse agregado el parametro.

Aqui les muestro otro ejemplo que refuerza lo que digo

public class Ejemplo {

    public static void main (String[] args) {
               
                Contenedor objCo=new Contenedor();
                Intermedio ObjIn=new Intermedio();
               
                objCo.setNombre("Pedro");
               
                System.out.println("Primer Valor de la Variable Nombre " + objCo.getNombre());
               
                ObjIn.m2(objCo);   //Se Agrega por REFERENCIA, el objeto ObjCo
               
                System.out.println("Segundo Valor de la Variable Nombre " + objCo.getNombre());
               
        }    
}
class Intermedio{
        public void m2(Contenedor b) {
          b.setNombre("Juan");
        }
}
class Contenedor{
        private String Nombre;
       
        public void setNombre(String Nombre){
                this.Nombre=Nombre;    
        }
        public String getNombre(){
                return this.Nombre;    
        }
}

Y da como resultado

--------------------Configuration: <Default>--------------------
Primer Valor de la Variable Nombre Pedro
Segundo Valor de la Variable Nombre Juan

Process completed.

Por estas razones, creo que:

"Java no permite pasar Tipos Primitivos como parametros "Directamente" por Referencia"

En Java Si existe el paso de parametros por Referencia pero esta limitado a los Objetos que no son Primitivos,

Y digo "Directamente" por que si no me ensartaria con los ejemplos que dio "@OscarRyz".

¿Entonces que tendriamos que hacer, para poder pasar un tipo Primitivo y/o String por Referencia?
Respuesta: Tenemos que Usar un Objeto que enmascare al tipo Primitivo y/o String ,tal como lo hizo "@OscarRyz" en su ejemplo

¿Pero existe alguna forma de hacerlo trasparente, sin necesidad de crear metodos (Setter) para modificar la variable?
Respuesta: Si Existe, se puede hacer con StringBuilder

Aqui un Ejemplo con paso de referencia con un Tipo String:

import javax.swing.*;

public class Dependiente {

    public static void main (String[] args) {
        ejemplo obj=new ejemplo();
       
        StringBuilder s = new StringBuilder();
        s.append("Abel");
        JOptionPane.showMessageDialog(null,"Primer Valor " + s.toString());
        obj.Metodo(s);
        JOptionPane.showMessageDialog(null,"Segundo Valor" + s.toString());
               
        }  
}
class ejemplo{
        public void Metodo(StringBuilder s){
                s.delete(0,s.length());
                s.append("Manuel");
        }
}

Aqui un Ejemplo con paso de referencia con un Tipo Int:

import javax.swing.*;

public class Dependiente {

    public static void main (String[] args) {
        ejemplo obj=new ejemplo();
       
        StringBuilder s = new StringBuilder();
        s.append(1);
        JOptionPane.showMessageDialog(null,"Primer Valor " + s.toString());
                obj.Metodo(s);
                JOptionPane.showMessageDialog(null,"Segundo Valor " + s.toString());
               
        }  
}
class ejemplo{
        public void Metodo(StringBuilder s){
                int Total=Integer.parseInt(s.toString());
                Total=+3;
                s.delete(0,s.length());
                s.append(Total);
        }
}

Suerte :)

Imagen de OscarRyz

...la función recibe la

...la función recibe la dirección de memoria del valor original, no la copia del valor...

Lo que pasa es que cuando se trata de objetos, lo que se recibe es "la copia del valor, de la referencia" ( esto hay que repetirlo hasta que quede claro)

Es decir, en Java, nunca y repito nunca se obtiene la referencia a un objeto ( como en Pascal/Delphi, C++ , VB, y otros lenguajes ) lo que se obtiene es el valor de la referencia. Cuando lo pasas entre métodos, lo que pasas el es valor de la referencia. Cuando cambias una variable, lo que cambias es el valor de la referencia por uno nuevo.

Ejemplo

Object o = new Object();

El objeto creado se va la memoria de Java ( al monton ) y la variable "o" tiene el "valor" de la referencia de ese objeto.

Si se define luego:

Object p = o;

La variable "p" tiene el mismo "valor" que la variable "o", pero si se cambia luego:

o = new Object();

La variable p sigue teniendo el valor anterior y la variable o uno nuevo.

En los lenguajes de programaicón que tiene paso por referencia cuando se cambia el segundo el primero también se modifica. Esto no es posible en Java.

El efecto que ves cuando le asignas otro valor de referencia a un atributo, es que en realidad sí le estas cambiando el valor por uno nuevo, pero parece que cambias la referencia:

Demo:

C:\>more > Bv.java
class W {
  Object o;
}
class T {
   public static void main( String ... args ) {
     W w = new W();
     w.o = new Object();
     Object p = w.o;
     System.out.println("p == w.o ? " + ( p == w.o ) );
     changeIt( w );
     System.out.println("p == w.o ? " + ( p == w.o ) );
   }
   public static void changeIt( W z ) {
        z.o = new Object();
    }
}
^C
C:\>javac Bv.java

C:\>java T
p == w.o ? true
p == w.o ? false

De nuevo, en los lenguajes que soportan pase por referencia, cuando la referencia es cambiada, todos las referencia al mismo objeto cambian tambien, es decir lo anterior imprimiría true en ambos casos.

Otros dos links:

http://javadude.com/articles/passbyvalue.htm
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1

Paso por Referencias. Gracias Chicos

Gracias a los 3 me han ayudado a entender un poco mas de la forma de pasar estos valores.
saludos desde venezuela.

Imagen de bferro

Modelo de objetos por valor y modelo de objetos por referencia

El paso por valor y el paso por referencias en lenguajes como Java y C++ tiene mucho que ver con los modelos de objetos que usa uno y otro lenguaje.
C++ utiliza un modelo de objetos "híbrido", producto de su relación muy estrecha con el lenguaje C de donde proviene. C++ es "híbrido" también en lo que se refiere al scope donde se pueden definir funciones.

En C++ se dice que existe un modelo de objetos por valor y un modelo de objetos por referencia o apuntadores como se le quiera llamar.

En el modelo de objetos por valor, la memoria asignada al objeto se localiza en el scope donde se crea, y la creación del objeto usa una sintaxis similar al la creación de variables de tipos definidos por el lenguaje.

El modelo de objetos por referencia (que para la creación de objetos usa al operador new) localiza la dirección o apuntador del objeto en el scope donde se crea, pero el espacio para el objeto se crea en otro lugar. Nos referimos a ese lugar como el espacio de objetos.

Java solamente tiene ese modelo de objetos por referencia.

Para lidear con un modelo de objetos por valor, C++ introduce el constructor copia o copy constructor, el que se invoca para varias cosas, entre ellas la del paso de objetos por valor.

C++ también introduce el tipo referencia, para hacer varias cosas, y entre ellas brindar lo que se denomina sintaxis de paso por valor con semántica de paso por referencia. Con esos tipos referencias podemos entonces decir que C++ incluye paso por valor y paso por referencia de los argumentos pasados a las funciones. Depende enteramente del compilador si crea en el espacio de las funciones un apuntador para "apuntar" al objeto de tipo referencia, pero para el programador eso es transparente: dispones de una sintaxis por valor con una semántica de apuntadores.

A continuación un ejemplo de esto en C++:

#include <iostream>
using namespace std;

class point {
public:
    //Constructor copia
    point(const point& bar) {
        this->x = 333;
        this->y = 666;
    }
    point(int x, int y) {
        this->x = x;
        this->y = y;
    }
    void set(double x, double y) {
        (*this).x = x;
        this->y = y;
    }
    //Función que recibe un objeto por valor
    point byValue(point foo) {
        foo.set (-foo.x,-foo.y);
        cout << "I am at(byValue)  " << foo.where_am_I() << endl;
        cout << "(" << foo.x << "," << foo.y << ")" << endl;
    }

    //Función que recibe un objeto por referencia
    point byReference(point& foo) {
        foo.set (-foo.x,-foo.y);
        cout << "I am  at(ByReference) " << foo.where_am_I() << endl;
        cout << "(" << foo.x << "," << foo.y << ")" << endl;
    }

    point* where_am_I() {
        return this;
    }
    double getX(){return x; }
    double getY(){return y; }

private:
    double x, y;
};

int main() {
    point a(111, 999);
    cout << "\na is at  " << a.where_am_I() << endl;
    a.byReference(a); //Se modifica el objeto recibido
    cout << "([a.x, a.y] " << a.getX() << "," << a.getY() << ")" << endl;

    a.set(111,999);
    cout << "\na is at   " << a.where_am_I() << endl;
    a.byValue(a); //No se modifica el objeto recibido
    cout << "([a.x, a.y] " << a.getX() << "," << a.getY() << ")" << endl;

    //Regresamos al valor original
    a.set(111,999);
    point* c = new point(444, 555);
    cout << "\nc is at   " << c->where_am_I() << endl;
    a.byValue(*c); //No se modifica el objeto recibido
    cout << "([c.x, c.y] " << c->getX() << "," << c->getY() << ")\n" << endl;
   
    a.byReference(*c); //No se modifica el objeto recibido
    cout << "([c.x, a.y] " << c->getX() << "," << c->getY() << ")" << endl;

}

Al ejecutar este código obtenemos lo siguiente:

a is at  0x22ccf8
I am  at(ByReference) 0x22ccf8
(-111,-999)
([a.x, a.y] -111,-999)

a is at   0x22ccf8
I am at(byValue)  0x22cd08
(-333,-666)
([a.x, a.y] 111,999)

c is at   0xfa0408
I am at(byValue)  0x22cd18
(-333,-666)
([c.x, c.y] 444,555)

I am  at(ByReference) 0xfa0408
(-444,-555)
([c.x, a.y] -444,-555)

El resultado expresa la localización de los objetos pasados por valor y pasados por referencia y la modificación de los atributos x, y para el caso de pasar un tipo referencia. También muestra el uso del constructor copia para el paso por valor.

Imagen de cyberserver

Chale, dos contra 1

Chale dos contra uno ni como decir que no, me lincha. jajaja!!! ntc!!!!

Sip @OscarRyz tienes razon :) con el ejemplo me quedo muy Claro tienes Razon :)

Imagen de OscarRyz

Una variación

Aquí va una variación al ejemplo de bferro. Le quité las llamadas a cout ( solo para mejorar la legibilidad ) e hice que dentro de los métodos se cree un nuevo objeto y se asigne al argumento pasado. El código dentro del los métodos es (casi) identico.

En uno ( byRef ) el argumento pasado toma el valor del nuevo objeto y al salir del método, conserva ese valor.

En otro ( byValue ) el argumento pasado toma el valor de nuevo objeto, pero lo descarta al salir del método ( como en Java ) y después de la invocación, conserva su valor original.

#include <iostream>
using namespace std;
class Punto
{

   public:
        int x,y;
       
        Punto(int x, int y )
        {
                this->x = x;
                this->y = y;
        }
        Punto* me()
        {
            return this;
        }

        void byRef(Punto& p )
        {
                Punto x(3,2);
                p = x;
                printf("-Dentro de byRef\n%p a(x=%d,y=%d)\n",p.me(), p.x, p.y);
        }
        void byValue( Punto p )
         {
                Punto x(4,5);
                p = x;
                printf("-Dentro de byValue\n%p a(x=%d,y=%d)\n",p.me(), p.x, p.y);
        }
};

main()
{
        Punto a(1,1);
        printf("-Original(antes)\n%p a(x=%d,y=%d)\n",a.me(), a.x, a.y);
        a.byRef(a);
       
        printf("\n-Despues de byRef\n%p a(x=%d,y=%d)\n",a.me(), a.x, a.y);     
        printf("La referencia original: ( %p ), ahora tiene el contenido de otro objeto\n\n", a.me());

        a.byValue(a);
        printf("-Despues de byValue\n%p a(x=%d,y=%d)\n",a.me(), a.x, a.y);
        printf("La referencia original: ( %p ) sigue teniendo el mismo contenido que antes\n", a.me());

        return(0);
}