salida - parámetros por valor y por referencia java




¿Cómo llamar por referencia en Java? (7)

Dado que Java no admite punteros, ¿cómo es posible llamar una función por referencia en Java como lo hacemos en C y C ++?


¿Cómo llamar por referencia en Java?

No se puede hacer llamada por referencia en Java. Período. Nada ni siquiera se acerca. Y pasar una referencia por valor NO es lo mismo que llamar por referencia.

(La verdadera "llamada por referencia" le permite hacer este tipo de cosas:

void swap(ref int i, ref int j) { int tmp = *i; *i = *j; *j = tmp }

int a = 1;
int b = 2;
swap(a, b);

Simplemente no puedes hacer eso en Java.)

Ya que Java no soporta punteros ...

Si bien esto es técnicamente cierto, no sería un impedimento para lo que está tratando de hacer.

Java admite referencias , que son como punteros en los aspectos más importantes. La diferencia es que no puede tratar las referencias como direcciones de memoria haciendo aritmética en ellas, convirtiéndolas desde y hacia tipos de enteros y así sucesivamente. Y no puede crear una referencia a una variable porque el concepto no existe en Java o en la arquitectura JVM.

¿Cómo es posible llamar a una función por referencia en Java como hacemos en C y C ++?

En Java, las funciones (métodos) y las referencias a las funciones no se admiten como valores. Por lo tanto, no puede pasarlos como argumentos y no puede asignarlos a variables.

Sin embargo, puede definir una clase con un método de instancia y usar una instancia de la clase en lugar de una referencia de función. Otras respuestas dan ejemplos de este enfoque.


El paso por referencia real es imposible en Java. Java pasa todo por valor, incluyendo referencias. Pero puedes simularlo con objetos contenedor.

Utilice cualquiera de estos como un parámetro del método:

  • una matriz
  • Una colección
  • una clase de AtomicXYZ

Y si cambia su contenido en un método, el contenido modificado estará disponible para el contexto de la llamada.

Vaya, aparentemente te refieres a llamar a un método por referencia. Esto tampoco es posible en Java, ya que los métodos no son ciudadanos de primer nivel en Java. Esto puede cambiar en JDK 8 , pero por el momento, tendrá que usar interfaces para evitar esta limitación.

public interface Foo{
    void doSomeThing();
}

public class SomeFoo implements Foo{
    public void doSomeThing(){
       System.out.println("foo");
    }
}

public class OtherFoo implements Foo{
    public void doSomeThing(){
       System.out.println("bar");
    }
}

Use Foo en su código, para que pueda sustituir fácilmente SomeFoo con OtherFoo .


From Java The Complete Reference de Herbert Shildt 9ª edición: "Cuando se pasa un objeto a un método, la situación cambia dramáticamente, porque los objetos se pasan por lo que es efectivamente llamada por referencia. Tenga en cuenta que al crear una variable de un tipo de clase, solo está creando una referencia a un objeto. Por lo tanto, cuando pasa esta referencia a un método, el parámetro que lo recibe se referirá al mismo objeto al que hace referencia el instrumento. Esto significa que los objetos actúan como si se pasan a métodos mediante el uso de llamada por referencia. Los cambios en el objeto dentro del método afectan al objeto utilizado como argumento ".

package objectpassing;

public class PassObjectTest {

    public static void main(String[] args) {
        Obj1 o1 = new Obj1(9);
        System.out.println(o1.getA());
        o1.setA(3);
        System.out.println(o1.getA());
        System.out.println(sendObj1(o1).getA());
        System.out.println(o1.getA());
    }

public static Obj1 sendObj1(Obj1 o)
{
    o.setA(2);
    return o;
}


}

class Obj1
{
    private int a;

    Obj1(int num)
    {
        a=num;
    }

    void setA(int setnum)
    {
        a=setnum;
    }

    int getA()
    {
        return a;
    }
}

OP: 9 3 2 2

La llamada final a getA () muestra que el campo de objeto original 'a' se cambió en la llamada al método público estático Obj1 sendObj1 (Obj1 o).


JAVA permite referencias internas utilizando objetos. Cuando uno escribe esta asignación Obj o1 = new Obj (); Obj o2 = o1; ¿Qué hace, que o1 y o2 apunten a la misma dirección? Manipulando el espacio de cualquier objeto, se reflejará también en el del otro.

Así que para hacer esto, como se mencionó anteriormente, puedes usar Array, Colecciones


La mejor manera es usar una interfaz que realice la acción.

// Pass a Runnable which calls the task() method
executor.submit(new Runnable() {
    public void run() {
        task();
    }
});

public void task() { }

Puedes usar reflexiones para llamar a cualquier método.

Method method = MyClass.class.getMethod("methodToCall", ParameterType.class);
result = method.invoke(object, args);

Normalmente en java esto se resuelve usando interfaces:

Collections.sort(list, new Comparator() {

  @Override
  public int compareTo(Object o1, Object o2) {
  /// code
  }

});

package jgf;

public class TestJavaParams {

 public static void main(String[] args) {
    int[] counter1 = new int[1];
    counter1[0] = 0;
    System.out.println(counter1[0]);
    doAdd1(counter1);
    System.out.println(counter1[0]);
    int counter2 = 0;
    System.out.println(counter2);
    doAdd2(counter2);
    System.out.println(counter2);   
  }

  public static void doAdd1(int[] counter1) {
    counter1[0] += 1;
  }

  public static void doAdd2(int counter2) {
    counter2 += 1;
  }
}

La salida sería:

0
1
0
0




function-calls