Java funkció létrehozása visszatérő adatokkal?
C++-ban így kéne létrehozni:
void f(int& a){
a=5;
}
int c=2;
f(c);
c==5; //IGAZ
Ezt hogy lehet javaba megcsinálni?
Returnt nem szeretnék használni.
#2 Tudtommal a Java mindig értéket ad át paraméterben, referenciát soha. Ráadásul az Integer osztály immuable típus, úgy ahogy az összes többi primitív típust burkoló wrapper osztály is, beleértve a Stringet, tehát nem lehet az értéküket módosítani. Javíts ki ha tévedek.
Ha több értéket kell visszaadni egy metódusból akkor a legtisztább ha készítesz egy saját osztályt és annak egy példányát adod vissza.
Ha a visszatérési értékek típusai megegyeznek, akkor egy tömbben is visszaadhatod őket:
return new int[] {foo, bar};
class Intecske {
int i;
public int get() { return i; }
public void set(int j) { i = j; }
}
void f(Intecske a) { a.set(5); }
// main:
Intecske c = 2;
f(c);
assert c.get() == 5;
#4 vagyok
akarom mondani
Intecske c = new Intecske();
c.set(2);
"#2 Tudtommal a Java mindig értéket ad át paraméterben, referenciát soha."
Minden objektum referenciaként megy át. A primitív típusok mennek másolással. Az objektumot clone hívással vagy copy konstruktorral lehet lemásolni, ha kell.
"Ráadásul az Integer osztály immuable típus"
Igen ezt benéztem, mert itt mutable Integer kell.Ahogy feljebb van.
> Minden objektum referenciaként megy át. A primitív típusok mennek másolással. Az objektumot clone hívással vagy copy konstruktorral lehet lemásolni, ha kell.
Akkor itt van egy kis félreértés. Amiről te beszélsz az a referencia értékének átadása ami szintén értékátadás és nem referenciaátadás. Érthető ez a félreértés. A referenciaátadás arról szól, hogy ha "kicseréled" az objektumot egy másikra, akkor ez a hívó metódusból is látszik, de itt nem érttől van szó. Gyors google után érdemes ezeket elolvasni, ők biztos jobban elmagyarázzák:
És akkor itt vissza is térünk az eredeti kérdésre:
Létezik e "T f(V& a)" Javaban?
A válasz az hogy nem, legyen a V primitív vagy osztály, teljesen mindegy. De ha átadsz egy mutable Wrapper objektumot, a tagváltozóit lehet ugyan úgy módosítani, mint ahogy azt C++-ban is lehet:
T f(W(V) a);
De ez nem ugyan az mint ha referenciával adnánk át, és ezzel sem egyenlő:
T f(W(V)& a);
#7-es:
Igen a referencia másolódik le (inkább pointer a hivatkozott oldalak szerint). Csak nekem (és lehet teljesen félreérettem ezt a dolgot) ez a referencia szerinti átadás. Oké értem a pass-by-value magyarázatát és én is azt mondom hogy a Java lemásolja a pointert, de a Java sehol nem beszél pointerről (illetve nincs pointer!). Pl. a tömb érték szerinti átadása a teljes tömb lemásolását jelentené nekem (mivel nincs pointerről szó a Java-ban, mert ez nem a C-s (T*) jelölés), amit a Java megint nem csinál meg. Tehát helyesen összefoglalva: nincs pointer a Javaban, de vannak dolgok amik pointer másolással mennek át, amiket referenciának hívnak, és érték szerint megy minden.
Amikor átadsz egy referenciát, azt át tudod írni úgy, hogy a referencia egy másik objektumra mutasson. Ez a referencia szerinti átadás.
Amit talán nem veszel észre, az talán az hogy ha a Java-ban minden objektum valójában egy referencia, akkor a referencia referenciáját kéne átadni hogy azt át lehessen írni. Ha a referencia értékét adod át, és azt egy másik referencia értékére írod át, kívülről nem fog látszani. Ez a lényegi különbség.
Alacsony szinten a referencia nagyon hasonlít a pointerre. Mivel Javaban az objektumok referenciák, tekintsük úgy mintha pointerről beszélnénk.
Ez történik Javaban:
{
T* foo;
f(foo);
}
[...]
void f(T* parm) {
T* bar
parm = bar
}
Látszik hogy itt értékként adtam át a pointert (referenciát), ha a függvényben felülírom az értékéket egy másikra, az kívülről nem látszik.
Hogy működjön, pointerként (referenciaként) kéne átadnom a pointert (referenciát):
{
T* foo;
f(&foo);
}
[...]
void f(T** parm) {
T* bar;
parm = &bar;
}
Ilyen nincs a Javaban. Ezért írják hogy nem referenciaként hanem értékként adják át a referenciát, és valójában teljesen független az egész attól hogy mit adunk át, referenciát vagy primitív típust, de az mindig értékként kerül átadásra. A félreértés abból adódik hogy az objektumok referenciák, tehát ha egy objektumot adunk át akkor egy referenciát adunk át, de ez teljesen lényegtelen információ a függvény szempontjából, mert nem létezik olyan hogy egy objektum nem referencia lenne úgy mint C++-ban. Bármit adunk át, legyen az primitív típus vagy egy objektum referenciája, az értékként kerül átadásra, soha nem referenciaként: egy konvenció az, hogy ha egy függvény paraméteréről beszélünk, akkor a függvény szemszögéből vizsgáljuk a paramétert. Ez egy apróságnak tűnik de a mondatod jelentését teljesen megváltoztatja, még akkor is ha másra gondolsz, persze mindketten értjük :)
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!