8
Everyone says that Java goes by value, including Objects. These are copied and cannot be reassigned to a new object within the method. The problem is that it is possible to change object values within the method. This does not characterize the passing by reference simulation (done with C pointers++)?
Example of Java Code
class Objeto {
public int valor;
public Objeto(){
this.valor = 2;
}
}
public class Passagem {
public static void main(String[] args) {
Objeto obj = new Objeto();
System.out.printf("Valor inicial: %d\n", obj.valor);
metodo(obj);
System.out.printf("Valor após o método: %d\n", obj.valor);
metodoNovo(obj);
System.out.printf("Valor após o método com novo objeto: %d\n", obj.valor);
}
// Simula a passagem por referência alterando o valor do objeto
// mas não o local de memória para qual aponta
static void metodo(Objeto obj){
obj.valor = 5;
}
//Tenta alterar o objeto em si
static void metodoNovo(Objeto obj){
obj = new Objeto();
obj.valor = 10;
}
}
The value of the object can be directly changed by the first method. Already in the second it is not possible to reassign it to a new object, even because the method expects to receive a constant Object - to change an object itself logic says that we would have to have an object to an object.
The example in C++, which behaves in the same way:
Code Example in C++
#include <iostream>
using std::cout;
using std::endl;
class Objeto{
public:
int valor;
Objeto(){
this->valor = 2;
}
};
void funcao(Objeto *obj){
obj->valor = 5;
}
void funcaoNovo(Objeto *obj){
obj = new Objeto();
obj->valor = 10;
}
int main()
{
Objeto *obj = new Objeto();
cout << "Valor inicial: " << obj->valor << endl;
funcao(obj);
cout << "Após função: " << obj->valor << endl;
funcaoNovo(obj);
cout << "Após função que atribui novo objeto: "
<< obj->valor << endl;
}
The result of the two codes is the same.
It is only possible to change the object itself in the C++ code if the function expects to receive the address of the object itself, as in:
C++ Function Changes Object
void funcaoNovo(Objeto **obj){
*obj = new Objeto();
(*obj)->valor = 10;
}
main to the above function
int main()
{
Objeto *obj = new Objeto();
cout << "Valor inicial: " << obj->valor << endl;
funcao(obj);
cout << "Após função: " << obj->valor << endl;
funcaoNovo(&obj);
cout << "Após função que atribui novo objeto: "
<< obj->valor << endl;
}
Where it will be possible to see that the reallocation has worked.
Based on these comparisons, it is right to say that in Java there is also a simulation of passing by reference? It is not possible to change the object (the location to which it points), but it is possible to change its values because the function (or method) caller directly changes the value of the values in the objects.
Note: In C it is also possible to do the same test. A given function funcao(int *ptr)
cannot assign the ptr
to a new malloc
within it. Only the value can be changed and is considered a passing simulation by reference.
My biggest doubt:
In C++ the object itself does not change the original value.
void funcaoNovo(Objeto *obj){
Objeto *novo = new Objeto();
novo->valor = 10;
obj = novo;
}
Here the obj
is not changed outside the function. In the same way as in Java.
That is, it is not possible to reassign an object either because C++ cannot change the object passed by copy as well. However can change the value contained in the object (here is the simulation), provided you do not try to change the object.
This is called a passing-by-reference simulation, because the calling function modifies the data contained in the Object and not the Object itself. Java has no reference passage (except with arrays), but it would not be correct to say that there is a simulation of this passage in the value to which the object references, ie I get a simulation when referencing the values?
Because I see that both passages are similar - they allow the function to change values outside the scope (including multiple values), without allowing pointer reallocation (Java reference).
I don’t know if I understand your editing, but in Java when you want to modify whole objects the common thing is to involve them in a "wrapper" (an object with reference to another object) and share this wrapper with all interested parties. Thus, if one of them changes the object instance, the other will get the new object when accessing the wrapper (provided they do not save a local copy of the object itself). This is more or less similar to the pointer to pointer, only a little more limited.
– mgibsonbr
To change a pointer, by allocating it in a new memory space, in C++ (or C) it takes exactly the same thing: a pointer to pointer. A pointer as a function parameter only ensures changing the value that the object (pointer) contains (or to which it points), not the object itself. Similarly a reference in Java, it can change values, to which it points, within the function that will have an effect outside it. As a pointer (analogous to the reference) does.
– Rafael Bluhm