Java ÔÇťreferansa g├ÂreÔÇŁ veya ÔÇťde─čere g├ÂreÔÇŁ m─▒?


Al─▒nan cevaba git


Java'n─▒n referans yoluyla oldu─čunu hep d├╝┼č├╝nd├╝m .

Ancak, olmad─▒─č─▒n─▒ iddia eden birka├ž blog yaz─▒s─▒ (├Ârne─čin, bu blog ) g├Ârd├╝m .

Yapt─▒klar─▒ ayr─▒m─▒ anlad─▒─č─▒m─▒ sanm─▒yorum.

A├ž─▒klama nedir?


6198









Cevap say─▒s─▒n─▒ say: 30






Java her zaman parola de─čeridir . Ne yaz─▒k ki, bir nesnenin de─čerini iletti─čimizde referans─▒ ona aktar─▒yoruz. Bu yeni ba┼člayanlar i├žin kafa kar─▒┼čt─▒r─▒c─▒.

Bu b├Âyle devam ediyor:

 public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}
 

Yukar─▒daki ├Ârnekte aDog.getName() yine d├Ânecektir "Max" . De─čeri aDog olan main i┼člevinde de─či┼čtirilmez foo ile Dog "Fifi" nesne referans de─čeri ge├žti─či ┼čekilde. O referans olarak ge├žirildi, sonra aDog.getName() i├žinde main d├Ânece─čini "Fifi" ├ža─čr─▒s─▒n─▒n foo .

Ayn─▒ ┼čekilde:

 public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}
 

Yukar─▒daki ├Ârnekte, nesnenin ad─▒ i├žinde ayarland─▒─č─▒ i├žin Fifi ├ža─čr─▒n─▒n ard─▒ndan k├Âpe─čin ad─▒d─▒r . O Herhangi operasyonlar ger├žekle┼čtirdi─či ├╝zerindeki t├╝m pratik ama├žlar i├žin, bunlar ├╝zerinde ger├žekle┼čtirilir, ┼čekildedir , ama ├Âyle de─čil de─či┼čkenin de─čerini de─či┼čtirmek m├╝mk├╝n kendisi. foo(aDog) foo(...) foo d aDog aDog


5524







Sadece yaz─▒ma at─▒fta bulundu─čunu fark ettim .

Java Spec, JavaÔÇÖdaki her ┼čeyin de─čerinden ge├žti─čini s├Âyl├╝yor. Java'da "referans yoluyla ge├žme" diye bir ┼čey yoktur.

Bunu anlaman─▒n anahtar─▒, bunun gibi bir ┼čey

 Dog myDog;
 

oldu─ču olmayan bir k├Âpek; bu asl─▒nda bir K├Âpe─čin i┼čaret├žisi .

Bunun anlam─▒, sen sahip oldu─čun zaman

 Dog myDog = new Dog("Rover");
foo(myDog);
 

asl─▒nda olu┼čturulan nesnenin adresini y├Ânteme aktar─▒yorsunuzdur. Dog foo

(Esasen, Java i┼čaret├žilerinin do─črudan adres olmad─▒─č─▒, ancak onlar─▒ bu ┼čekilde d├╝┼č├╝nmenin en kolay yolu oldu─čunu s├Âyl├╝yorum)

Dog Nesnenin 42 numaral─▒ haf─▒za adresinde bulundu─čunu varsayal─▒m. Bu, 42 metodunu ge├žece─čimiz anlam─▒na gelir.

Y├Ântem olarak tan─▒mland─▒ysa

 public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}
 

Neler oldu─čuna bir bakal─▒m.

  • parametre someDog 42 de─čerine ayarlan─▒r
  • "AAA" sat─▒r─▒nda
    • someDog kadar takip edilir Dog i├žin bu puan ( Dog adresinde nesne 42)
    • o Dog (adresinde 42 az bir) Max ismini de─či┼čtirmek istenir
  • "BBB" sat─▒r─▒nda
    • yeni Dog bir yarat─▒ld─▒. Diyelim ki 74 adresinde.
    • parametreyi someDog 74'e atad─▒k
  • "CCC" sat─▒r─▒nda
    • someDog Dog i┼čaret etti─či yere do─čru hareket eder ( Dog adres 74'deki nesne)
    • o Dog (adresinde 74 az bir) Rowlf ismini de─či┼čtirmek istenir
  • o zaman geri d├Âneriz

┼×imdi, y├Ântemin d─▒┼č─▒nda ne olaca─č─▒n─▒ d├╝┼č├╝nelim:

De─či┼čti myDog mi?

Anahtar var.

Bunun myDog bir i┼čaret├ži oldu─čunu ve ger├žek olmad─▒─č─▒n─▒ ak─▒lda tutarak Dog cevab─▒m HAYIR. myDog yine de 42 de─čerine sahiptir; hala orjinaline i┼čaret ediyor Dog (ama "AAA" sat─▒r─▒ nedeniyle ad─▒n─▒n art─▒k "Max" - hala ayn─▒ Dog'un; myDog de─čerinin de─či┼čmedi─čine dikkat edin.)

Bir adresi takip etmek ve sonunda olanlar─▒ de─či┼čtirmek tamamen ge├žerli ; Ancak bu de─či┼čkeni de─či┼čtirmez.

Java tam olarak C gibi ├žal─▒┼č─▒r. Bir i┼čaret├žiyi atayabilir, i┼čaret├žiyi bir y├Ânteme iletebilir, i┼čaret├žiyi y├Ântemdeki i┼čaret├žiyi takip edebilir ve i┼čaret edilen verileri de─či┼čtirebilirsiniz. Ancak, bu i┼čaret├žinin i┼čaret etti─či yeri de─či┼čtiremezsiniz.

C ++, Ada, Pascal ve referans referanslar─▒n─▒ destekleyen di─čer dillerde, asl─▒nda ge├žen de─či┼čkeni de─či┼čtirebilirsiniz.

E─čer Java referans-anlam semanti─čine foo sahip olsayd─▒, yukar─▒da tan─▒mlad─▒─č─▒m─▒z y├Ântem BBB sat─▒r─▒na myDog atand─▒─č─▒nda i┼čaret etti─či yeri de─či┼čtirirdi someDog .

Referans parametrelerini, iletilen de─či┼čken i├žin takma isim olarak d├╝┼č├╝n├╝n. Bu takma ad atand─▒─č─▒nda, iletilen de─či┼čken de ├Âyle.


2919







Java her zaman de─či┼čkenleri referansa g├Âre DE─×─░L de─čerlere g├Âre iletir.


Bunu bir ├Ârnekle a├ž─▒klayay─▒m :

 public class Main{
     public static void main(String[] args){
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }
     public static void changeReference(Foo a){
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c){
          c.setAttribute("c");
     }
}
 

Bunu ad─▒m ad─▒m a├ž─▒klayaca─č─▒m:

  1. f Type adl─▒ bir ba┼čvuruyu bildirme Foo ve ona Foo nitelik i├žeren yeni bir t├╝r nesnesi atama "f" .

     Foo f = new Foo("f");
     


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

  2. Metot taraf─▒ndan, Foo isimde bir tip referans─▒ a bildirildi ve ba┼člang─▒├žta atand─▒ null .

     public static void changeReference(Foo a)
     


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

  3. Y├Ântemi ├ža─č─▒rd─▒─č─▒n─▒zda, changeReference ba┼čvuru a ba─č─▒ms─▒z de─či┼čken olarak iletilen nesneye atanacakt─▒r.

     changeReference(f);
     


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

  4. b Type adl─▒ bir ba┼čvuruyu bildirme Foo ve ona Foo nitelik i├žeren yeni bir t├╝r nesnesi atama "b" .

     Foo b = new Foo("b");
     


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

  5. a = b referans i├žin yeni bir atama yapar a , de─čil f , olan ├Âznitelik nesnenin "b" .


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin


  6. Siz modifyReference(Foo c) y├Ântem ├ža─č─▒rd─▒─č─▒n─▒zda , bir referans c yarat─▒l─▒r ve nesneye ├Âzniteli─či atan─▒r "f" .


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

  7. c.setAttribute("c"); ba┼čvuruyu c i┼čaret eden nesnenin niteli─čini de─či┼čtirecek ve ona i┼čaret eden nesnenin niteli─čini de─či┼čtirecektir f .


    g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Umar─▒m nesnelerin arg├╝man olarak ge├žirilmesinin Java'da nas─▒l ├žal─▒┼čt─▒─č─▒n─▒ ┼čimdi anlars─▒n─▒z :)


1634







Bu, Java'n─▒n ger├žekte nas─▒l ├žal─▒┼čt─▒─č─▒ hakk─▒nda baz─▒ bilgiler verecek, Java ile ilgili bir sonraki tart─▒┼čman─▒zda, referansa g├Âre ya da de─čere g├Âre ge├žme konusundaki tart─▒┼čmalar─▒n─▒zda sadece g├╝l├╝mseyece─činiz :-)

Birinci ad─▒m, ├Âzellikle di─čer programlama dillerinden geliyorsan─▒z, 'p' "_ _ _ _ _ _ _" ile ba┼člayan kelimeyi akl─▒n─▒zdan ├ž─▒kar─▒n─▒z. Java ve 'p' ayn─▒ kitapta, forumda ve hatta txt'te yaz─▒lamaz.

─░kinci ad─▒m, bir Nesneyi bir y├Ânteme iletti─činizde, Nesne'nin kendisinden de─čil, Nesne ba┼čvurusunu ge├žti─činizi hat─▒rlay─▒n.

  • ├ľ─črenci : Usta, bu Java'n─▒n referans yoluyla ge├žti─či anlam─▒na m─▒ geliyor?
  • Master : ├çekirge, No.

┼×imdi bir Nesnenin referans─▒n─▒n / de─či┼čkeninin ne yapt─▒─č─▒n─▒ / oldu─čunu d├╝┼č├╝n├╝n:

  1. Bir de─či┼čken, JVM'ye bellekteki ba┼čvurulan Nesne'ye nas─▒l ula┼č─▒laca─č─▒n─▒ s├Âyleyen bitleri tutar.
  2. Ba─č─▒ms─▒z de─či┼čkenleri bir y├Ânteme iletirken, referans de─či┼čkenini DE─×─░L, ancak referans de─či┼čkenindeki bitlerin bir kopyas─▒n─▒ alamazs─▒n─▒z . Bunun gibi bir ┼čey: 3bad086a. 3bad086a, iletilen nesneye ula┼čman─▒n bir yolunu g├Âsterir.
  3. Yani sadece referans olarak 3bad086a ge├žiyorsunuz.
  4. Referans─▒n de─čerini ge├žiyorsunuz, referans─▒n kendisinden de─čil (nesneden de─čil).
  5. Bu de─čer asl─▒nda COPIED ve metoda verilmi┼čtir .

A┼ča─č─▒da (l├╝tfen bunu derlemeye / y├╝r├╝tmeye ├žal─▒┼čmay─▒n─▒z ...):

 1. Person person;
2. person = new Person("Tom");
3. changeName(person);
4.
5. //I didn't use Person person below as an argument to be nice
6. static void changeName(Person anotherReferenceToTheSamePersonObject) {
7.     anotherReferenceToTheSamePersonObject.setName("Jerry");
8. }
 

Ne oluyor?

  • De─či┼čken ki┼či # 1 sat─▒r─▒nda olu┼čturulur ve ba┼člang─▒├žta bo┼č b─▒rak─▒l─▒r.
  • 2 numaral─▒ sat─▒rda yeni bir Ki┼či Nesnesi olu┼čturulur, bellekte saklan─▒r ve de─či┼čken ki┼čiye Ki┼či nesnesine referans verilir. Bu, adresi. 3bad086a diyelim.
  • Nesnenin adresini tutan de─či┼čken ki┼či # 3 sat─▒r─▒ndaki i┼čleve iletilir.
  • 4. sat─▒rda sessizli─čin sesini dinleyebilirsiniz.
  • 5. sat─▒rdaki yorumu kontrol edin
  • Bir yerel de─či┼čken y├Ântemi - anotherReferenceToTheSamePersonObject - olu┼čturulur ve sihir # 6 sat─▒r─▒na gelir:
    • De─či┼čken / referans ki┼či bit bit kopyalan─▒r ve i┼člev i├žindeki ba┼čka birReferenceToTheSamePersonObject ├Â─česine ge├žirilir .
    • Yeni bir Ki┼či ├Ârne─či olu┼čturulmad─▒.
    • Hem " person " hem de " anotherReferenceToTheSamePersonObject " ayn─▒ 3bad086a de─čerini tutar.
    • Bunu denemeyin ama person == anotherReferenceToTheSamePersonObject do─čru olurdu.
    • Her iki de─či┼čken de referans─▒n K─░ML─░K KOPYALARINA sahiptir ve her ikisi de ayn─▒ Ki┼či Nesnesine, Y─▒─č─▒n ├╝zerindeki AYNI Nesne'ye ve A KOPYALAMA DE─×─░LD─░R.

Bir resim bin kelime de─čerinde bir olup:


De─čere G├Âre Ge├ž

AnotherReferenceToTheSamePersonObject oklar─▒n─▒n, de─či┼čken ki┼čiye de─čil, Nesneye y├Ânelik oldu─čunu unutmay─▒n!

E─čer anlamad─▒ysan, bana g├╝ven ve Java'n─▒n de─čere g├Âre ge├žti─čini s├Âylemenin daha iyi oldu─čunu unutma . Peki, referans de─čerine g├Âre ge├ž . Ah, daha da iyisi, de─či┼čken de─čerinin kopyadan kopyalanmas─▒d─▒r! ;)

┼×imdi benden nefret etmekten ├žekinmeyin, ancak buna bak─▒ld─▒─č─▒nda, y├Ântem arg├╝manlar─▒ hakk─▒nda konu┼čurken ilkel veri t├╝rlerini ve Nesneleri ge├žmek aras─▒nda bir fark olmad─▒─č─▒n─▒ unutmay─▒n .

Her zaman referans─▒n de─čerinin bitlerinin bir kopyas─▒n─▒ iletirsiniz!

  • ─░lkel bir veri t├╝r├╝ ise, bu bitler ilkel veri t├╝r├╝n├╝n kendisinin de─čerini i├žerecektir.
  • Bir Nesne ise, bitler JVM'ye Nesne'ye nas─▒l ula┼č─▒laca─č─▒n─▒ s├Âyleyen adresin de─čerini i├žerecektir.

Java, parola de─čeridir, ├ž├╝nk├╝ bir y├Ântemin i├žinde ba┼čvurulan Nesneyi istedi─činiz kadar de─či┼čtirebilirsiniz, ancak ne kadar u─čra┼č─▒rsan─▒z ├žal─▒┼č─▒n, ba┼čvuruyu s├╝rd├╝recek olan de─či┼čkeni hi├žbir zaman de─či┼čtiremezsiniz (p _ _ _ de─čil _ _ _ _) ne olursa olsun ayn─▒ Nesne!


Yukar─▒daki changeName i┼člevi hi├žbir zaman iletilen ba┼čvurunun as─▒l i├žeri─čini (bit de─čerleri) de─či┼čtiremez. Ba┼čka bir deyi┼čle changeName, Person ki┼čisinin ba┼čka bir Nesneyi y├Ânlendirmesini sa─člayamaz.


Tabii ki k─▒sa kesebilir ve sadece Java'n─▒n parola de─čeri oldu─čunu s├Âyleyebilirsiniz !


710







Java her zaman bunun istisnas─▒ de─čeriyle ge├žmesi oldu─čunu hi├ž .

├ľyleyse, herkesin bununla kar─▒┼čt─▒─č─▒ nas─▒l olabilir ve Java'n─▒n referans yoluyla ge├žti─čine ya da referans olarak ge├žen Java ├Ârne─čine sahip olduklar─▒na inan─▒yor? Kilit noktas─▒ Java olmas─▒d─▒r asla de─čerlerine do─črudan eri┼čim sa─člar kendileri nesneler i├žinde, herhangi bir ko┼čul. Nesnelere tek eri┼čim , o nesneye yap─▒lan bir referanst─▒r . Java nesneleri ├ç├╝nk├╝ her zaman bir referans ├╝zerinden eri┼čilen yerine do─črudan yerine, alanlar ve de─či┼čkenlerin bahsetmek yayg─▒nd─▒r ve y├Ântem arg├╝manlar olarak nesnelerin ukalal─▒kla onlar sadece, nesnelere ba┼čvurular . Kar─▒┼č─▒kl─▒k, terminolojideki bu (kesinlikle konu┼čma, yanl─▒┼č) de─či┼čimin sonucudur.

Yani, bir y├Ântem ├ža─č─▒r─▒rken

  • ─░lkel arg├╝manlar ( int , long vb.) ─░├žin de─čere g├Âre ge├ži┼č , ilkel de─čerin ger├žek de─čeridir (├Ârne─čin, 3).
  • Nesneler i├žin de─čere g├Âre ge├ži┼č, nesneye yap─▒lan ba┼čvurunun de─čeridir .

├ľyleyse, siz doSomething(foo) ve public void doSomething(Foo foo) { .. } iki Foos ayn─▒ nesneleri i┼čaret eden referanslar─▒ kopyalad─▒larsa .

Do─čal olarak, bir nesneye bir referans─▒n de─čerini iletmek, bir nesneyi referans yoluyla ge├žirmek gibi g├Âr├╝nmektedir (ve pratikte ay─▒rt edilemez).


646







Java referanslar─▒ de─čere g├Âre iletir.

Yani, al─▒nan referans─▒ de─či┼čtiremezsiniz.


310







"Referansa g├Âre pass-by-value-pass-value" hakk─▒nda tart─▒┼čmak gibi hissediyorum s├╝per yararl─▒ de─čildir.

"Java her ne pahas─▒na olursa olsun (ba┼čvuru / de─čer)" derseniz, her iki durumda da tam bir cevap veremezsiniz. ─░┼čte bellekte neler olup bitti─čini anlamada yard─▒mc─▒ olacak baz─▒ ek bilgiler.

Java uygulamas─▒na ge├žmeden ├Ânce y─▒─č─▒nda / y─▒─č─▒nda ├žarp─▒┼čma rotas─▒: De─čerler, bir kafeteryadaki bir tabak y─▒─č─▒n─▒ gibi, g├╝zel ve d├╝zenli bir ┼čekilde y─▒─č─▒n─▒n ├╝zerine ├ž─▒kar. Y─▒─č─▒n i├žindeki bellek (ayn─▒ zamanda dinamik bellek olarak da bilinir) geli┼čig├╝zel ve d├╝zensizdir. JVM m├╝mk├╝n olan her yerde yer bulur ve onu kullanan de─či┼čkenler art─▒k gerekmedi─činden onu serbest b─▒rak─▒r.

Tamam. ├ľncelikle, yerel ilkel y─▒─č─▒nda gider. Yani bu kod:

 int x = 3;
float y = 101.1f;
boolean amIAwesome = true;
 

bunun sonucu:


y─▒─č─▒ndaki ilkeller

Bir nesneyi bildirdi─činizde ve ba┼člatt─▒─č─▒n─▒zda. Ger├žek nesne ├Âbek ├╝zerinde gider. Y─▒─č─▒na ne oluyor? ├ľbek ├╝zerindeki nesnenin adresi. C ++ programc─▒lar─▒ buna bir i┼čaret├ži derdi, fakat baz─▒ Java geli┼čtiricileri "pointer" kelimesine kar┼č─▒lar. Her neyse. Sadece nesnenin adresinin y─▒─č─▒nda oldu─čunu biliyorum.

Gibi:

 int problems = 99;
String name = "Jay-Z";
 


ab * 7ch bir de─čil!

Bir dizi bir nesnedir, yani ├Âb├╝r yere de gider. Peki ya dizideki nesneler? Kendi y─▒─č─▒n alanlar─▒n─▒ al─▒rlar ve her nesnenin adresi dizinin i├žine gider.

 JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");
 


marx karde┼čler

├ľyleyse, bir y├Ântem ├ža─č─▒rd─▒─č─▒n─▒zda ne aktar─▒l─▒r? Bir nesneye ge├žerseniz, asl─▒nda iletti─činiz nesnenin adresidir. Baz─▒lar─▒ adresin "de─čerini" s├Âyleyebilir ve baz─▒lar─▒ bunun yaln─▒zca nesneye referans oldu─čunu s├Âyleyebilir. Bu, "referans" ve "de─čer" savunucular─▒ aras─▒ndaki kutsal sava┼č─▒n ortaya ├ž─▒k─▒┼č─▒d─▒r. Buna ne diyorsun, i├žeri girenlerin nesnenin adresi oldu─čunu anlaman kadar ├Ânemli de─čil.

 private static void shout(String name){
    System.out.println("There goes " + name + "!");
}

public static void main(String[] args){
    String hisName = "John J. Jingleheimerschmitz";
    String myName = hisName;
    shout(myName);
}
 

Bir Dize olu┼čturulur ve bunun i├žin yer ayr─▒l─▒r ve dizeye olan adres y─▒─č─▒nda depolan─▒r ve tan─▒mlay─▒c─▒ verilir hisName , ├ž├╝nk├╝ ikinci Dize adresi ilk ile ayn─▒d─▒r, yeni Dize olu┼čturulmaz ve yeni bir y─▒─č─▒n alan─▒ tahsis edilmez, ancak y─▒─č─▒nda yeni bir tan─▒mlay─▒c─▒ olu┼čturulur. Daha sonra ├ža─č─▒r─▒r─▒z shout() : yeni bir y─▒─č─▒n ├žer├ževesi yarat─▒l─▒r ve yeni bir tan─▒mlay─▒c─▒ name yarat─▒l─▒r ve hali haz─▒rda var olan Dize'nin adresini belirler.


la da di da da da da da

├ľyleyse, de─čer, referans? "Patates" diyorsun.


222







Sadece kar┼č─▒tl─▒─č─▒ g├Âstermek i├žin, a┼ča─č─▒daki C ++ ve Java par├žac─▒klar─▒n─▒ kar┼č─▒la┼čt─▒r─▒n:

C ++ 'da: Not: Hatal─▒ kod - bellek s─▒z─▒nt─▒s─▒! Ancak bu noktas─▒ g├Âstermektedir.

 void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
    val = 7; // Modifies the copy
    ref = 7; // Modifies the original variable
    obj.SetName("obj"); // Modifies the copy of Dog passed
    objRef.SetName("objRef"); // Modifies the original Dog passed
    objPtr->SetName("objPtr"); // Modifies the original Dog pointed to 
                               // by the copy of the pointer passed.
    objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                   // leaving the original object alone.
    objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to 
                                    // by the original pointer passed. 
    objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}

int main()
{
    int a = 0;
    int b = 0;
    Dog d0 = Dog("d0");
    Dog d1 = Dog("d1");
    Dog *d2 = new Dog("d2");
    Dog *d3 = new Dog("d3");
    cppMethod(a, b, d0, d1, d2, d3);
    // a is still set to 0
    // b is now set to 7
    // d0 still have name "d0"
    // d1 now has name "objRef"
    // d2 now has name "objPtr"
    // d3 now has name "newObjPtrRef"
}
 

JavaÔÇÖda

 public static void javaMethod(int val, Dog objPtr)
{
   val = 7; // Modifies the copy
   objPtr.SetName("objPtr") // Modifies the original Dog pointed to 
                            // by the copy of the pointer passed.
   objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                  // leaving the original object alone.
}

public static void main()
{
    int a = 0;
    Dog d0 = new Dog("d0");
    javaMethod(a, d0);
    // a is still set to 0
    // d0 now has name "objPtr"
}
 

Java yaln─▒zca iki ge├ži┼č t├╝r├╝ne sahiptir: yerle┼čik t├╝rler i├žin de─čere ve nesne t├╝rleri i├žin i┼čaret├žinin de─čerine g├Âre.


181







Java referanslar─▒ nesnelere de─čerine g├Âre iletir.


160







Temel olarak, Nesne parametrelerinin yeniden atanmas─▒ arg├╝man─▒ etkilemez, ├Ârn.

 private void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}
 

"Hah!" yerine yazd─▒racak null . Bunun i┼če yaramas─▒n─▒n nedeni , sadece referans olan bar de─čerinin bir kopyas─▒ . Ger├žek referans kendisi olsayd─▒, o zaman yeniden olurdu etmek . baz "Hah!" foo baz null


156







Hen├╝z kimsenin Barbara Liskov'dan bahsetmedi─čine inanam─▒yorum. O 1974 y─▒l─▒nda CLU'yu tasarlanm─▒┼č, o bu ayn─▒ terminoloji sorun ko┼čtu ve o d├Ânem icat payla┼č─▒m─▒ ├ža─čr─▒y─▒ (olarak da bilinen nesne payla┼č─▒m─▒ yoluyla ├ža─čr─▒ ve obje taraf─▒ndan ├ža─čr─▒ de─čeridir de─čerle ├ža─čr─▒s─▒" bu ├Âzel durum i├žin) referans".


146







Meselenin ├Âz├╝ kelime olmas─▒d─▒r referans ifadesinde kelime ola─čan anlam─▒ tamamen farkl─▒ ara├žlar ┼čey "referans ge├žmek" referans Java.

Genellikle Java referans─▒nda bir nesneye referans anlam─▒na gelir . Ancak programlama terimleri teorisindeki referans / de─čerden ge├žen teknik terimler de─či┼čkenleri tutan bellek h├╝cresine yap─▒lan bir referanstan bahsediyor , ki bu tamamen farkl─▒ bir ┼čey.


110







Point pnt1 = new Point(0,0); Java'da her ┼čey referanst─▒r, yani ┼č├Âyle bir ┼čeyiniz oldu─čunda: Java a┼ča─č─▒dakileri yapar:

  1. Yeni Point nesnesi olu┼čturur
  2. Yeni Point referans─▒ olu┼čturur ve bu referans─▒ daha ├Ânce olu┼čturulan Point nesnesindeki noktaya (bak─▒n─▒z) ba┼člat─▒r .
  3. Buradan, Point nesne ├Âmr├╝ boyunca, bu nesneye pnt1 ba┼čvurusu yoluyla eri┼čeceksiniz. B├Âylece Java'da nesneyi referans─▒ ile de─či┼čtirdi─činizi s├Âyleyebiliriz.


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Java, y├Ântem arg├╝manlar─▒na referans olarak ge├žmez; onlar─▒ de─čere g├Âre iletir. Bu siteden ├Ârnek kullanaca─č─▒m :

 public static void tricky(Point arg1, Point arg2) {
  arg1.x = 100;
  arg1.y = 100;
  Point temp = arg1;
  arg1 = arg2;
  arg2 = temp;
}
public static void main(String [] args) {
  Point pnt1 = new Point(0,0);
  Point pnt2 = new Point(0,0);
  System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y); 
  System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
  System.out.println(" ");
  tricky(pnt1,pnt2);
  System.out.println("X1: " + pnt1.x + " Y1:" + pnt1.y); 
  System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);  
}
 

Program─▒n ak─▒┼č─▒:

 Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
 

─░li┼čkili iki farkl─▒ referansla iki farkl─▒ Point nesnesi olu┼čturma.
g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

 System.out.println("X1: " + pnt1.x + " Y1: " +pnt1.y); 
System.out.println("X2: " + pnt2.x + " Y2: " +pnt2.y);
System.out.println(" ");
 

Beklendi─či gibi ├ž─▒kt─▒ olacakt─▒r:

 X1: 0     Y1: 0
X2: 0     Y2: 0
 

Bu sat─▒rda 'by-value-pass' oyuna giriyor ...

 tricky(pnt1,pnt2);           public void tricky(Point arg1, Point arg2);
 

Referanslar pnt1 ve pnt2 edilmektedir de─čer ge├žirilecek zor y├Ânteme, art─▒k senin referanslar ara├žlar─▒ pnt1 ve pnt2 bunlar─▒n sahip copies adland─▒r─▒l─▒r arg1 ve arg2 .bu pnt1 ve arg1 noktalar ayn─▒ nesneye. (Ayn─▒ i├žin pnt2 ve arg2 )
g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Bu tricky y├Ântemde:

  arg1.x = 100;
 arg1.y = 100;
 


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Bir sonraki tricky y├Ântem

 Point temp = arg1;
arg1 = arg2;
arg2 = temp;
 

Burada, ilk ├Ânce temp referansla ayn─▒ yere i┼čaret edecek yeni Nokta referans─▒ arg1 yarat─▒rs─▒n─▒z. Sonra ba┼čvuru ta┼č─▒mak arg1 i├žin noktadan gibi ayn─▒ yere arg2 referans. Nihayet arg2 edecek i┼čaret gibi ayn─▒ yere temp .


g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Buradan kapsam─▒ tricky y├Ântemine gitti ve referanslar art─▒k eri┼čiminiz yok: arg1 , arg2 , temp . Ama di─čer ├Ânemli nokta ise oldu─čunda 'Hayatta' bu referanslarla yapmak her ┼čeyin kal─▒c─▒ olduklar─▒n─▒ nesneyi etkileyecek olan nokta i├žin.

Bu nedenle tricky , y├Ântemi y├╝r├╝tt├╝kten sonra , geri d├Ând├╝─č├╝n├╝zde main , ┼ču duruma sahipsiniz:
g├Âr├╝nt├╝ tan─▒m─▒n─▒ buraya girin

Yani ┼čimdi, tamamen program─▒n y├╝r├╝t├╝lmesi olacakt─▒r:

 X1: 0         Y1: 0
X2: 0         Y2: 0
X1: 100       Y1: 100
X2: 0         Y2: 0
 

80







Java her zaman de─čere g├Âre ge├žer, referansa g├Âre de─čil

├ľncelikle, de─čere g├Âre ge├žen ve referansa g├Âre ge├ženlerin ne oldu─čunu anlamam─▒z gerekir.

De─čere g├Âre ge├žmek, iletilen ger├žek parametrenin de─čerinin haf─▒zas─▒na bir kopya yapt─▒─č─▒n─▒z anlam─▒na gelir. Bu, ger├žek parametrenin i├žeri─činin bir kopyas─▒d─▒r .

Referansa g├Âre g├Ânder (ayr─▒ca adrese g├Âre de adland─▒r─▒l─▒r), ger├žek parametrenin adresinin bir kopyas─▒n─▒n sakland─▒─č─▒ anlam─▒na gelir .

Bazen Java referans olarak ge├ži┼č yan─▒lsamas─▒ verebilir. A┼ča─č─▒daki ├Ârne─či kullanarak nas─▒l ├žal─▒┼čt─▒─č─▒n─▒ g├Ârelim:

 public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeValue(t);
        System.out.println(t.name);
    }

    public void changeValue(Test f) {
        f.name = "changevalue";
    }
}

class Test {
    String name;
}
 

Bu program─▒n ├ž─▒kt─▒s─▒:

 changevalue
 

Ad─▒m ad─▒m anlayal─▒m:

 Test t = new Test();
 

Hepimizin bildi─či gibi, y─▒─č─▒n i├žinde bir nesne yaratacak ve referans de─čerini t'ye geri d├Ând├╝recektir. ├ľrne─čin, t'nin de─čerini varsayal─▒m 0x100234 (ger├žek JVM dahili de─čerini bilmiyoruz, bu sadece bir ├Ârnek).


ilk ill├╝strasyon

 new PassByValue().changeValue(t);
 

Referans t'ye fonksiyona ge├žilirken do─črudan nesne testinin ger├žek referans de─čerini ge├žmez, ancak t'nin bir kopyas─▒n─▒ olu┼čturur ve ard─▒ndan fonksiyona ge├žirir. Bu oldu─čundan de─čeri ge├žirerek , bu de─či┼čken de─čil, bunun yerine ger├žek bir referans kopyas─▒n─▒ ge├žer. T'nin de─čeri dedi─čimiz i├žin 0x100234 , hem t hem de f ayn─▒ de─čere sahip olacak ve dolay─▒s─▒yla ayn─▒ nesneye i┼čaret edeceklerdir.


ikinci ├Ârnek

F i┼člevini kullanarak i┼člevdeki herhangi bir ┼čeyi de─či┼čtirirseniz, nesnenin varolan i├žeri─čini de─či┼čtirir. Bu y├╝zden changevalue fonksiyonda g├╝ncellenen ├ž─▒kt─▒y─▒ ald─▒k .

Bunu daha net anlamak i├žin a┼ča─č─▒daki ├Ârne─či g├Âz ├Ân├╝nde bulundurun:

 public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeRefence(t);
        System.out.println(t.name);
    }

    public void changeRefence(Test f) {
        f = null;
    }
}

class Test {
    String name;
}
 

Bu atar NullPointerException m─▒? Hay─▒r, ├ž├╝nk├╝ yaln─▒zca referans─▒n bir kopyas─▒n─▒ veriyor. Referans ile ge├žilmesi durumunda, NullPointerException a┼ča─č─▒da g├Âr├╝ld├╝─č├╝ gibi, a at─▒lm─▒┼č olabilir :


├╝├ž├╝nc├╝ ├Ârnek

Umar─▒m bu yard─▒mc─▒ olacakt─▒r.


77







Ba┼čvuru, hangi dili kullan─▒yor olursan─▒z olun, temsil edildi─činde her zaman bir de─čerdir.

Kutu g├Âr├╝n├╝m├╝n├╝n d─▒┼č─▒na ├ž─▒kmadan derleme veya d├╝┼č├╝k seviye bellek y├Ânetimine bakal─▒m. CPU seviyesinde , herhangi bir ┼čeye yap─▒lan bir referans , belle─če veya CPU kay─▒tlar─▒ndan birine yaz─▒ld─▒─č─▒nda derhal bir de─čere d├Ân├╝┼č├╝r . (Bu nedenle i┼čaret├ži iyi bir tan─▒md─▒r. Ayn─▒ zamanda bir amac─▒ olan bir de─čerdir).

Bellekteki verilerin bir Konumu var ve o konumda bir de─čer var (bayt, kelime, her neyse). Derlemede , belirli Konumlara (aka de─či┼čken) bir Ad vermek i├žin uygun bir ├ž├Âz├╝me sahibiz , ancak kodu derlerken, assembler Ad─▒n─▒z─▒ yaln─▒zca taray─▒c─▒n─▒zdaki alan adlar─▒n─▒ IP adresleriyle de─či┼čtirdi─či gibi belirtilen konumla de─či┼čtirir.

├çekirde─če kadar, herhangi bir dilde bir referans─▒ temsil etmeden (hemen bir de─čer oldu─čunda) teknik olarak m├╝mk├╝n de─čildir.

Diyelim ki Foo de─či┼čkenimiz var, Konumu haf─▒zada 47. bayta ve De─čeri 5. Diyelim ki haf─▒zada 223 byte olan bir ba┼čka de─či┼čken Ref2Foo var ve de─čeri 47 olacak. Bu Ref2Foo teknik bir de─či┼čken olabilir. , a├ž─▒k├ža program taraf─▒ndan yarat─▒lmad─▒. Ba┼čka hi├žbir bilgi olmadan sadece 5. ve 47'ye bakarsan─▒z, sadece iki De─čer g├Âreceksiniz . Bunlar─▒ referans olarak kullan─▒rsan─▒z ula┼čmak 5 i├žin seyahat etmemiz gerekir:

 (Name)[Location] -> [Value at the Location]
---------------------
(Ref2Foo)[223]  -> 47
(Foo)[47]       -> 5
 

Bu, atlama masalar─▒n─▒n ├žal─▒┼čma ┼čeklidir.

Foo'nun de─čerine sahip bir y├Ântem / i┼člev / prosed├╝r ├ža─č─▒rmak istiyorsak, dile ve birka├ž y├Ântem ba┼člatma kipine ba─čl─▒ olarak de─či┼čkeni y├Ânteme iletmenin birka├ž olas─▒ yolu vard─▒r :

  1. 5, CPU kay─▒tlar─▒ndan birine kopyalan─▒r (├Ârn. EAX).
  2. 5, PUSHd'yi y─▒─č─▒na al─▒r.
  3. 47 CPU kay─▒tlar─▒ndan birine kopyaland─▒
  4. 47 PUSHd y─▒─č─▒na.
  5. CPU kay─▒tlar─▒ndan birine 223 kopyaland─▒.
  6. 223 PUSHd'yi y─▒─č─▒na al─▒yor.

Bir de─čerin ├╝zerindeki her durumda - mevcut bir de─čerin bir kopyas─▒ - yarat─▒lm─▒┼čt─▒r, ┼čimdi bunu ele almak i├žin al─▒c─▒ y├Ânteme kalm─▒┼čt─▒r. E─čer y├Ântem i├žinde "Foo" yazarken, o da otomatik olarak EAX d─▒┼čar─▒ okumak, ya da indirgenmedikleri , ya da ├žift indirgenmedikleri, s├╝re├ž, dil bilgisi ve / veya ne Foo emirlerine tipi ba─čl─▒d─▒r. Bu, yeniden d├╝zenleme i┼člemini ortadan kald─▒rana kadar geli┼čtiriciden gizlenir. Bu nedenle referans temsil edildi─činde bir de─čerdir , ├ž├╝nk├╝ referans i┼členmesi gereken bir de─čerdir (dil d├╝zeyinde).

┼×imdi Foo'yu y├Ânteme ge├žirdik:

  • 1. ve 2. durumlarda, Foo ( Foo = 9 ) ' yu de─či┼čtirirseniz, De─čer'in bir kopyas─▒na sahip oldu─čunuzdan yaln─▒zca yerel kapsam─▒ etkiler. Y├Ântemin i├žinden, orijinal FooÔÇÖnun nereye kaydedildi─čini bile belirleyemiyoruz.
  • 3. ve 4. durumlarda, e─čer varsay─▒lan dil yap─▒lar─▒n─▒ kullan─▒r ve Foo ( Foo = 11 ) ' yu de─či┼čtirirseniz , k├╝resel olarak FooÔÇÖyu de─či┼čtirebilir (dile ba─čl─▒ olarak, yani Java ya da PascalÔÇÖ─▒n var procedure findMin(x, y, z: integer; mÔÇÖsi gibi : integer); ). Dil KQUEUE s├╝reci a┼čmak i├žin izin verirse Ancak, de─či┼čtirebilir 47 , s├Âyleyecek 49 . Bu noktada, e─čer okursan─▒z Foo de─či┼čtirilmi┼č g├Âr├╝n├╝yor, ├ž├╝nk├╝ yerel g├Âstericiyi de─či┼čtirdiniz . Ve e─čer bu Foo'yu y├Ântem ( Foo = 12 ) i├žinde de─či┼čtirecekseniz , muhtemelen program─▒n y├╝r├╝t├╝lmesini FUBAR yapacaks─▒n─▒z (aka segfault) ├ž├╝nk├╝ beklenenden farkl─▒ bir belle─če yazacaks─▒n─▒z, ├žal─▒┼čt─▒r─▒labilir tutulacak bir alan─▒ bile de─či┼čtirebilirsiniz programlamak ve ona yazmak ├žal─▒┼čan kodu de─či┼čtirecektir (Foo ┼ču anda de─čil 47 ). AMA Foo'nun de─čeri 47 global olarak de─či┼čmedi, yaln─▒zca y├Ântemin i├žindeki bir de─čerdi , ├ž├╝nk├╝ 47 ayn─▒ zamanda y├Ântemin bir kopyas─▒yd─▒.
  • 5. ve 6. durumlarda 223 , y├Ântemin i├žinde de─či┼čiklik yaparsan─▒z , 3. veya 4. ile ayn─▒ karga┼čay─▒ yarat─▒r (┼čimdi k├Ât├╝ bir de─čere i┼čaret eden bir i┼čaret├ži, yine i┼čaret├ži olarak kullan─▒l─▒r), ancak bu hala yerel sorun, 223 kopyaland─▒─č─▒ gibi . E─čer dereference edebiliyoruz Ancak e─čer Ref2Foo (yani 223 kadar), eri┼čim ve sivri de─čerini de─či┼čtirmek 47 , diyelim ki, 49 bu Foo etkileyecek k├╝resel Bu durumda y├Ântemler bir kopyas─▒ var ├ž├╝nk├╝, 223 ancak ba┼čvurulan 47 yaln─▒zca bir kez bulunuyorsa ve o de─či┼čen i├žin 49 her yol a├žacakt─▒r Ref2Foo yanl─▒┼č de─čere ├žift referanslanmas─▒.

├ľnemsiz detaylar ├╝zerine hafif├že vurmak, referans yoluyla ge├žen diller bile, fonksiyonlara de─čerleri iletecek, ancak bu fonksiyonlar, ba┼čvurular─▒ geciktirme amac─▒yla kullanmak zorunda olduklar─▒n─▒ biliyor. Bu referans-de─čeri-referans─▒ sadece programlay─▒c─▒dan gizlenir ├ž├╝nk├╝ pratik olarak faydas─▒zd─▒r ve terminoloji sadece referans-referans─▒d─▒r .

Kesin de─čer ge├ži┼č de─čeri de kullan─▒┼čs─▒zd─▒r, bu, diziyi her arg├╝man olarak bir y├Ântem ├ža─č─▒rd─▒─č─▒m─▒zda her 100 Mbayt dizinin kopyalanmas─▒ gerekti─či anlam─▒na gelir, bu nedenle Java karakteristik olarak de─či┼čtirilemez. Her dil bu b├╝y├╝k diziye (de─čer olarak) bir ba┼čvuru iletir ve e─čer bu dizi y├Ântem i├žinde yerel olarak de─či┼čtirilebilirse ya da y├Ântemin (Java'n─▒n yapt─▒─č─▒ gibi) diziyi global olarak de─či┼čtirmesine izin verirse ya da yazma ├╝zerine kopya mekanizmas─▒ kullan─▒r. Arayan─▒n g├Âr├╝n├╝m├╝) ve birka├ž dil referans─▒n de─čerini de─či┼čtirmeye izin verir.

Yani k─▒sacas─▒ ve Java'n─▒n kendi terminolojisinde, Java oldu─čunu pass-by-de─čeri nerede de─čeri bir ya: olabilmektedir ger├žek de─čeri veya de─čer bir bir temsilidir referans .


68







Java, de─čere g├Âre bir arama

Nas─▒l ├žal─▒┼č─▒r

  • Her zaman referans─▒n de─čerinin bitlerinin bir kopyas─▒n─▒ iletirsiniz!

  • Bu ilkel bir veri t├╝r├╝d├╝r, bu bitler ilkel veri t├╝r├╝n├╝n kendisinin de─čerini i├žerir, bu nedenle y├Ântem i├žindeki ba┼čl─▒─č─▒n de─čerini de─či┼čtirirsek, o zaman d─▒┼č─▒ndaki de─či┼čiklikleri yans─▒tmaz.

  • Foo foo = new Foo () gibi bir nesne veri t├╝r├╝ ise , bu durumda nesnenin adresinin kopyas─▒ dosya k─▒sayolu gibi ge├žiyorsa , C: \ masa├╝st├╝nde bir abc.txt metin dosyas─▒na sahip oldu─čumuzu ve k─▒sayol yapt─▒─č─▒m─▒z─▒ varsayal─▒m. Ayn─▒ dosyay─▒ C: \ desktop \ abc-shortcut i├žine yerle┼čtirin, b├Âylece dosyaya C: \ desktop \ abc.txt dosyas─▒ndan eri┼čti─činizde ve 'Stack Overflow' yaz─▒p dosyay─▒ kapatt─▒─č─▒n─▒zda dosyay─▒ tekrar k─▒sayoldan a├ž─▒n. write 'programlay─▒c─▒lar─▒n ├Â─črenmesi i├žin en b├╝y├╝k ├ževrimi├ži topluluktur' ve sonra toplam dosya de─či┼čikli─či 'Stack Overflow programlay─▒c─▒lar─▒n ├Â─črenmesi i├žin en b├╝y├╝k ├ževrimi├ži topluluktur' anlam─▒na gelir; ayn─▒ dosya, i┼čte varsayabiliriz foo bir dosya ve saklanan varsayal─▒m foo olarak 123hd7h (gibi ├Âzg├╝n adres : \ masa├╝st├╝ \ abc.txt C adres ve) 234jdid (kopyalanan adres gibi C: \ masa├╝st├╝ \ abc-k─▒sayol asl─▒nda i├žeren dosyan─▒n orjinal adresi) .. B├Âylece daha iyi anlamak i├žin k─▒sayol dosyas─▒ yap─▒n ve hissedin.


59







Bildi─čim kadar─▒yla, Java yaln─▒zca de─čere g├Âre aramay─▒ biliyor. Bu, ilkel veri t├╝rleri i├žin bir kopya ile ├žal─▒┼čaca─č─▒n─▒z ve nesneler i├žin referans─▒n bir kopyas─▒yla ├žal─▒┼čaca─č─▒n─▒z nesneler anlam─▒na gelir. Ancak baz─▒ tuzaklar oldu─čunu d├╝┼č├╝n├╝yorum; ├Ârne─čin, bu i┼če yaramayacak:

 public static void swap(StringBuffer s1, StringBuffer s2) {
    StringBuffer temp = s1;
    s1 = s2;
    s2 = temp;
}


public static void main(String[] args) {
    StringBuffer s1 = new StringBuffer("Hello");
    StringBuffer s2 = new StringBuffer("World");
    swap(s1, s2);
    System.out.println(s1);
    System.out.println(s2);
}
 

Bu, D├╝nya Merhaba'y─▒ de─čil D├╝nya Merhaba'y─▒ dolduracak ├ž├╝nk├╝ takas i┼člevinde ana referanslar─▒ etkilemeyen kopyalar─▒ kullan─▒rs─▒n─▒z. Ancak nesnelerinizin de─či┼čmez olmas─▒ durumunda, ├Ârne─čin:

 public static void appendWorld(StringBuffer s1) {
    s1.append(" World");
}

public static void main(String[] args) {
    StringBuffer s = new StringBuffer("Hello");
    appendWorld(s);
    System.out.println(s);
}
 

Bu, Hello World'├╝ komut sat─▒r─▒nda dolduracak. StringBuffer'─▒ String'e de─či┼čtirirseniz, String de─či┼čmez oldu─ču i├žin sadece Merhaba ├╝retecektir. ├ľrne─čin:

 public static void appendWorld(String s){
    s = s+" World";
}

public static void main(String[] args) {
    String s = new String("Hello");
    appendWorld(s);
    System.out.println(s);
}
 

Bununla birlikte, String gibi bir dizgeyi, onu Dizgilerle kullanabilmesini sa─člar:

 class StringWrapper {
    public String value;

    public StringWrapper(String value) {
        this.value = value;
    }
}

public static void appendWorld(StringWrapper s){
    s.value = s.value +" World";
}

public static void main(String[] args) {
    StringWrapper s = new StringWrapper("Hello");
    appendWorld(s);
    System.out.println(s.value);
}
 

edit: Ben bunun ayn─▒ zamanda StringBuffer'─▒ iki dizgiyi "eklemeye" geldi─činde kullanman─▒n da sebebi oldu─čuna inan─▒yorum ├ž├╝nk├╝ String gibi de─či┼čmez nesnelerle yapamayaca─č─▒n─▒z orijinal nesneyi de─či┼čtirebiliyorsunuz.


53







Hay─▒r, referans olarak ge├žmedi.

Java, Java Dil Belirtimi'ne g├Âre de─čere g├Âre iletilir:

Y├Ântem veya yap─▒c─▒ ├ža─čr─▒ld─▒─č─▒nda (┬ž15.12), ger├žek arg├╝man ifadelerinin de─čerleri , y├Ântemin veya yap─▒c─▒n─▒n g├Âvdesinin y├╝r├╝t├╝lmesinden ├Ânce, bildirilen t├╝rlerin her biri yeni olu┼čturulan parametre de─či┼čkenlerini ba┼člat─▒r . Beyannamede g├Âr├╝nen Tan─▒mlay─▒c─▒, bi├žimsel parametreye ba┼čvurmak i├žin y├Ântemin veya yap─▒c─▒n─▒n g├Âvdesinde basit bir ad olarak kullan─▒labilir .


53







Anlay─▒┼č─▒m─▒ d├Ârt ├Ârnekle a├ž─▒klamaya ├žal─▒┼čay─▒m. Java, by-pass de─čeridir ve referans by-pass de─čildir.

/ **

De─čere G├Âre Ge├ž

Java'da, t├╝m parametreler de─čere g├Âre iletilir, yani bir y├Ântem arg├╝man─▒ atama arayan taraf─▒ndan g├Âr├╝nmez.

* /

├ľrnek 1:

 public class PassByValueString {
    public static void main(String[] args) {
        new PassByValueString().caller();
    }

    public void caller() {
        String value = "Nikhil";
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}
 

Sonu├ž

 output : output
value : Nikhil
valueflag : false
 

├ľrnek 2:

/ ** * * De─čerine G├Âre Ge├ži┼č * * /

 public class PassByValueNewString {
    public static void main(String[] args) {
        new PassByValueNewString().caller();
    }

    public void caller() {
        String value = new String("Nikhil");
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}
 

Sonu├ž

 output : output
value : Nikhil
valueflag : false
 

├ľrnek 3:

/ ** Bu 'De─čerine G├Âre Ge├ži┼č' referans─▒na g├Âre ge├ži┼č 'hissine sahip

Baz─▒ insanlar ilkel t├╝rlerin ve 'Dize'nin' de─čere g├Âre ge├ž 've nesnelerin' referansa g├Âre ge├ž 'oldu─čunu s├Âyler.

Ancak bu ├Ârnekte, referans─▒n de─čer olarak ge├žti─čimizi ak─▒lda tutarak ak─▒lda tutman─▒n yaln─▒zca de─čere g├Âre ge├žti─čini anlayabiliriz. yani: referans de─čere g├Âre iletilir. Bu nedenle de─či┼čebiliyor ve hala yerel kapsamdan sonra ge├žerli. Ancak as─▒l referans─▒ orijinal kapsam─▒n d─▒┼č─▒nda de─či┼čtiremeyiz. Bunun anlam─▒, bir sonraki PassByValueObjectCase2 ├Ârne─či ile g├Âsterilmi┼čtir.

* /

 public class PassByValueObjectCase1 {

    private class Student {
        int id;
        String name;
        public Student() {
        }
        public Student(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + "]";
        }
    }

    public static void main(String[] args) {
        new PassByValueObjectCase1().caller();
    }

    public void caller() {
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student);
    }

    public String method(Student student) {
        student.setName("Anand");
        return "output";
    }
}
 

Sonu├ž

 output : output
student : Student [id=10, name=Anand]
 

├ľrnek 4:

/ **

├ľrnek 3'te (PassByValueObjectCase1.java) belirtilenlere ek olarak, as─▒l referans─▒ orijinal kapsam d─▒┼č─▒nda de─či┼čtiremeyiz. "

Not: i├žin kodu yap─▒┼čt─▒rm─▒yorum private class Student . ─░├žin s─▒n─▒f tan─▒m─▒ Student ├ľrnek 3 ile ayn─▒d─▒r.

* /

 public class PassByValueObjectCase2 {

    public static void main(String[] args) {
        new PassByValueObjectCase2().caller();
    }

    public void caller() {
        // student has the actual reference to a Student object created
        // can we change this actual reference outside the local scope? Let's see
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student); // Will it print Nikhil or Anand?
    }

    public String method(Student student) {
        student = new Student(20, "Anand");
        return "output";
    }

}
 

Sonu├ž

 output : output
student : Student [id=10, name=Nikhil]
 

50







Java'da referans olarak asla ge├žemezsiniz ve a├ž─▒k olan yollardan biri, bir y├Ântem ├ža─čr─▒s─▒ndan birden fazla de─čer d├Ând├╝rmek istedi─činiz zamand─▒r. A┼ča─č─▒daki kod bitini C ++ 'da d├╝┼č├╝n├╝n:

 void getValues(int& arg1, int& arg2) {
    arg1 = 1;
    arg2 = 2;
}
void caller() {
    int x;
    int y;
    getValues(x, y);
    cout << "Result: " << x << " " << y << endl;
}
 

Bazen ayn─▒ ┼čablonu Java'da kullanmak istersiniz, ancak kullanamazs─▒n─▒z; en az─▒ndan do─črudan de─čil. Bunun yerine b├Âyle bir ┼čey yapabilirsiniz:

 void getValues(int[] arg1, int[] arg2) {
    arg1[0] = 1;
    arg2[0] = 2;
}
void caller() {
    int[] x = new int[1];
    int[] y = new int[1];
    getValues(x, y);
    System.out.println("Result: " + x[0] + " " + y[0]);
}
 

├ľnceki cevaplarda a├ž─▒kland─▒─č─▒ gibi, Java'da bir i┼čaret├žiyi diziye bir de─čer olarak ge├žiriyorsunuz getValues . Bu yeterlidir, ├ž├╝nk├╝ y├Ântem daha sonra dizi ├Â─česini de─či┼čtirir ve kural olarak, ├Â─če 0'─▒n d├Ân├╝┼č de─čerini i├žermesini beklersiniz. A├ž─▒k├žas─▒ bunu, kodunuzu yap─▒land─▒rmak, b├Âylece gerekli olmamak veya d├Ân├╝┼č de─čerini i├žeren veya ayarlanmas─▒na izin verecek bir s─▒n─▒f olu┼čturmak gibi ba┼čka yollarla yapabilirsiniz. Fakat yukar─▒daki C ++ 'da bulabilece─činiz basit kal─▒p Java'da mevcut de─čildir.


47







┼×artnameden daha fazla ayr─▒nt─▒ eklemek i├žin bu cevaba katk─▒da bulunaca─č─▒m─▒ d├╝┼č├╝nd├╝m.

─░lk olarak, referansa g├Âre ge├žmekle de─čere g├Âre ge├žmek aras─▒ndaki fark nedir?

Referansa g├Âre ge├žmek, ├ža─čr─▒lan i┼člevlerin parametresi arayanlar─▒n iletilen arg├╝man─▒yla ayn─▒ olaca─č─▒ anlam─▒na gelir (de─čer de─čil, kimlik - de─či┼čkenin kendisi).

De─čere g├Âre ge├žmek, ├ža─čr─▒lan i┼člevlerin 'parametresinin arayanlar─▒n iletilen arg├╝man─▒n─▒n bir kopyas─▒ olaca─č─▒ anlam─▒na gelir.

Ya da wikipedia'dan referans yoluyla

Referans ├ža─čr─▒s─▒ de─čerlendirmesinde (ayn─▒ zamanda referans referans─▒ olarak da adland─▒r─▒l─▒r), bir fonksiyon, de─čerinin bir kopyas─▒ yerine, ba─č─▒ms─▒z de─či┼čken olarak kullan─▒lan bir de─či┼čkene ├Ârt├╝k bir referans al─▒r. Bu genellikle, i┼člevin arg├╝man olarak kullan─▒lan de─či┼čkeni de─či┼čtirebilece─či (yani atad─▒─č─▒) anlam─▒na gelir - arayan taraf─▒ndan g├Âr├╝lebilecek bir ┼čey.

Ve pass-by-de─čer konusunda

By-value ├ža─čr─▒s─▒nda, arg├╝man ifadesi de─čerlendirilir ve elde edilen de─čer, fonksiyondaki [...] kar┼č─▒l─▒k gelen de─či┼čkene ba─član─▒r. ─░┼člev veya prosed├╝r parametrelerine de─čer atayabiliyorsa, yaln─▒zca yerel kopyas─▒ atan─▒r [...].

─░kincisi, Java'n─▒n y├Ântem ├ža─čr─▒m─▒nda ne kulland─▒─č─▒n─▒ bilmemiz gerekir. Java Dil ┼×artname devletler

Y├Ântem veya yap─▒c─▒ ├ža─čr─▒ld─▒─č─▒nda (┬ž15.12), ger├žek arg├╝man ifadelerinin de─čerleri , y├Ântemin veya yap─▒c─▒n─▒n g├Âvdesinin y├╝r├╝t├╝lmesinden ├Ânce, bildirilen t├╝rlerin her biri yeni olu┼čturulan parametre de─či┼čkenlerini ba┼člat─▒r .

Bu nedenle, arg├╝man─▒n de─čerini kar┼č─▒l─▒k gelen parametre de─či┼čkenine atar (veya ona ba─člar).

Arg├╝man─▒n de─čeri nedir?

Java Sanal Makine Belirtimi durumlar─▒n─▒ referans t├╝rlerine g├Âre inceleyelim

├ť├ž t├╝r referans tipi vard─▒r : s─▒n─▒f tipleri, dizi tipleri ve aray├╝z tipleri. Onlar─▒n de─čerleri, s─▒ras─▒yla aray├╝zleri uygulayan dinamik olarak olu┼čturulmu┼č s─▒n─▒f ├Ârnekleri, diziler veya s─▒n─▒f ├Ârnekleri veya dizilere referanslard─▒r.

Java Dil ┼×artname ayr─▒ca devletler

Referans de─čerleri (genellikle sadece referanslar) bu nesnelere g├Âstericiler ve hi├žbir nesneye i┼čaret etmeyen ├Âzel bir bo┼č referanst─▒r.

Bir arg├╝man─▒n de─čeri (baz─▒ referans t├╝rlerinde) bir nesneye i┼čaret├židir. Bir de─či┼čkenin, bir referans t├╝r├╝ d├Ân├╝┼č t├╝r├╝ne sahip bir y├Ântemin ├ža─čr─▒lmas─▒n─▒n ve bir ├Ârnek olu┼čturma ifadesinin ( new ... ) hepsinin bir referans t├╝r├╝ de─čerine ├ž├Âz├╝mlendi─čini unutmay─▒n.

Yani

 public void method (String param) {}
...
String var = new String("ref");
method(var);
method(var.toString());
method(new String("ref"));
 

t├╝m├╝ String , y├Ântemin yeni olu┼čturulan parametresine bir ├Ârne─če yap─▒lan ba┼čvurunun de─čerini ba─člar param ,. Bu tam olarak de─čer-ge├ži┼č tan─▒m─▒n─▒n tan─▒mlad─▒─č─▒ ┼čeydir. Bu nedenle, Java parola de─čeridir .

Bir y├Ântemi ├ža─č─▒rmak veya ba┼čvurulan nesnenin bir alan─▒na eri┼čmek i├žin referans─▒ takip edebilmeniz, konu┼čma ile tamamen alakas─▒zd─▒r. Referansa g├Âre ge├ži┼č tan─▒m─▒

Bu genellikle, i┼člevin arg├╝man olarak kullan─▒lan de─či┼čkeni de─či┼čtirebilece─či (yani atad─▒─č─▒) anlam─▒na gelir - arayan taraf─▒ndan g├Âr├╝lebilecek bir ┼čey.

Java'da, de─či┼čkeni de─či┼čtirmek, onu yeniden atamak anlam─▒na gelir. Java'da, de─či┼čkeni y├Ântem i├žinde yeniden atad─▒ysan─▒z, arayan ki┼čiye fark edilmez. De─či┼čken taraf─▒ndan ba┼čvurulan nesneyi de─či┼čtirmek tamamen farkl─▒ bir kavramd─▒r.


─░lkel de─čerler, burada Java Sanal Makine Belirtimi'nde de tan─▒mlanm─▒┼čt─▒r . T├╝r├╝n de─čeri, uygun ┼čekilde kodlanm─▒┼č kar┼č─▒l─▒k gelen integral veya kayan nokta de─čeridir (8, 16, 32, 64 vb. Bit).


46







Bunu kapsayan zaten harika cevaplar var. C ++ 'dan referansa g├Âre Ge├ži┼č ile Java' dan de─čere g├Âre ge├ži┼č aras─▒ndaki davran─▒┼ča z─▒tl─▒k olu┼čturan ├žok basit bir ├Ârnek (derleme yapacak) payla┼čarak k├╝├ž├╝k bir katk─▒ yapmak istedim .

Birka├ž puan:

  1. "Referans" terimi, iki ayr─▒ anlam─▒ olan bir a┼č─▒r─▒ y├╝klenmedir. Java'da basit├že bir i┼čaret├ži anlam─▒na gelir, ancak "Referansa g├Âre atla" ba─člam─▒nda, i├žinde ge├žirilen orijinal de─či┼čkene bir tan─▒t─▒c─▒ anlam─▒na gelir.
  2. Java, Parola De─čeridir , ancak parolay─▒ bir Java referans─▒n─▒ (├Ârne─čin bir i┼čaret├ži) de─čerine g├Âre ge├žirerek referans olmam─▒z─▒ sa─člar. Yani Java referans─▒n─▒n bir kopyas─▒n─▒ ge├žer. EDIT : Birisi bu konuda bir yorum yapt─▒─č─▒ndan, a├ž─▒klamama izin verin. C'den ├Ânce, FORTRAN ve COBOL gibi daha ├Ânceki diller (hepsi de─čil) PBR'yi destekliyordu, fakat C desteklemiyordu. Fonksiyonlar─▒n i├žindeki de─či┼čkenlerin de─čerlerini de─či┼čtirmek i├žin, C programc─▒lar─▒, g├Âstergeleri de─či┼čkenlere fonksiyonlara d├Ân├╝┼čt├╝rerek PBR'yi taklit etti. Java gibi C'den ilham alan diller bu fikri ├Âd├╝n├ž ald─▒ ve PBR'yi C gibi taklit etmeye devam ediyor.
  3. C ++ , "&" karakterini kullanarak (hem C hem de C ++ 'da "bir de─či┼čkenin adresini" belirtmek i├žin kullan─▒lan ayn─▒ karakter olur), bir referans parametresi bildirerek Referans Referans─▒na izin verir . ├ľrne─čin, bir i┼čaret├žiyi referans olarak iletirsek, parametre ve arg├╝man sadece ayn─▒ nesneyi g├Âstermez. Aksine, bunlar ayn─▒ de─či┼čkendir. Biri farkl─▒ bir adrese veya bo┼č de─čere ayarlan─▒rsa, di─čeri de olur.
  4. A┼ča─č─▒daki C ++ ├Ârne─činde, bir i┼čaret├žiyi referans olarak bo┼č bir sonland─▒r─▒lm─▒┼č dizeye iletiyorum . Ve a┼ča─č─▒daki Java ├Ârne─činde, bir Java referans─▒n─▒ bir String'e (yine, String'in i┼čaret├žisine benzer ┼čekilde) de─čerine g├Âre iletiyorum. Yorumlardaki ├ž─▒kt─▒lara dikkat edin.

C ++ referans ├Ârne─či ile ge├žer:

 using namespace std;
#include <iostream>

void change (char *&str){   // the '&' makes this a reference parameter
    str = NULL;
}

int main()
{
    char *str = "not Null";
    change(str);
    cout<<"str is " << str;      // ==>str is <null>
}
 

Java, de─čer ├Ârne─čine g├Âre "bir Java referans─▒n─▒" ge├žer

 public class ValueDemo{

    public void change (String str){
        str = null;
    }

     public static void main(String []args){
        ValueDemo vd = new ValueDemo();
        String str = "not null";
        vd.change(str);
        System.out.println("str is " + str);    // ==> str is not null!!
                                                // Note that if "str" was
                                                // passed-by-reference, it
                                                // WOULD BE NULL after the
                                                // call to change().
     }
}
 

D├ťZENLE

Baz─▒ insanlar, ya benim ├Ârnekleriime bakmad─▒klar─▒n─▒ ya da c ++ ├Ârne─čini almad─▒klar─▒n─▒ belirten yorumlar yazm─▒┼člard─▒r. Ba─člant─▒ kesmenin nerede oldu─čundan emin de─čilsiniz, ancak c ++ ├Ârne─čini tahmin etmek net de─čil. Ayn─▒ ├Ârne─či pascal olarak g├Ânderiyorum, ├ž├╝nk├╝ referanstaki referans pascal'da daha temiz g├Âr├╝n├╝yor, ancak hatal─▒ olabilirim. ─░nsanlar─▒ daha fazla kar─▒┼čt─▒r─▒yor olabilirim; Umar─▒m de─čildir.

Pascal uygulamas─▒nda, referans taraf─▒ndan iletilen parametrelere "var parametreler" denir. A┼ča─č─▒daki SetANil prosed├╝r├╝nde, l├╝tfen 'ptr' parametresinden ├Ânce gelen 'var' anahtar s├Âzc├╝─č├╝n├╝ not al─▒n. Bir i┼čaret├ži bu prosed├╝re ge├žti─činde referans ile ge├žilir . Davran─▒┼ča dikkat edin: Bu yordam ptr'yi nil'e ayarlarsa (NULL i├žin pascal konu┼čur), arg├╝man─▒ nil olarak ayarlar - Java'da bunu yapamazs─▒n─▒z.

 program passByRefDemo;
type 
   iptr = ^integer;
var
   ptr: iptr;

   procedure setToNil(var ptr : iptr);
   begin
       ptr := nil;
   end;

begin
   new(ptr);
   ptr^ := 10;
   setToNil(ptr);
   if (ptr = nil) then
       writeln('ptr seems to be nil');     { ptr should be nil, so this line will run. }
end.
 

EDIT 2

Ken Arnold, James Gosling (Java'y─▒ icat eden ki┼či) ve David Holmes, b├Âl├╝m 2, b├Âl├╝m 2.6.5'ten "Java Programlama Dili" nden al─▒nt─▒lar

Y├Ântemlere t├╝m parametreler "de─čere g├Âre" iletilir . Ba┼čka bir deyi┼čle, bir y├Ântemdeki parametre de─či┼čkenlerinin de─čerleri, arg├╝man olarak belirtilen invokerin kopyalar─▒d─▒r.

Nesnelerle ilgili ayn─▒ ┼čeyi yapmaya devam ediyor. . .

Parametre bir nesne ba┼čvurusu oldu─čunda, nesnenin kendisinin de─čil, "de─čerine g├Âre" iletildi─či nesne ba┼čvurusu oldu─čunu unutmay─▒n .

Ve ayn─▒ b├Âl├╝m├╝n sonuna do─čru java'n─▒n yaln─▒zca de─čere g├Âre ge├žti─či ve asla referans olarak ge├žmedi─či hakk─▒nda daha geni┼č bir a├ž─▒klama yapar.

Java programlama dili nesneleri referans olarak iletmez; bu de─čer nesne referanslar─▒ ge├žer . Ayn─▒ referans─▒n iki kopyas─▒ ayn─▒ ger├žek nesneye at─▒fta bulundu─čundan, bir referans de─či┼čkeninde yap─▒lan de─či┼čiklikler di─čerinde g├Âr├╝lebilir. Tam olarak bir parametre ge├žirme modu var - de─čere g├Âre ge├ži┼č - ve i┼čleri basit tutmaya yard─▒mc─▒ olur.

Kitab─▒n bu b├Âl├╝m├╝nde Java'da ge├žen parametre ile referansa g├Âre verilen ve de─čere g├Âre verilen de─čer ile Java'n─▒n yarat─▒c─▒s─▒ aras─▒ndaki fark─▒n b├╝y├╝k bir a├ž─▒klamas─▒ vard─▒r. Bir kimseyi okumaya te┼čvik ediyorum, ├Âzellikle de ikna olmuyorsan─▒z.

─░ki model aras─▒ndaki fark─▒n ├žok ince oldu─čunu d├╝┼č├╝n├╝yorum ve referans referans─▒ kulland─▒─č─▒n─▒z yerde programlama yapmad─▒ysan─▒z, iki modelin nerede farkl─▒ oldu─čunu kolayca g├Ârmek ├žok kolay.

Umar─▒m bu tart─▒┼čmalar─▒ ├ž├Âzer ama muhtemelen ├ž├Âzmez.

EDIT 3

Bu yaz─▒ya biraz tak─▒nt─▒l─▒ olabilirim. Muhtemelen, Java ├╝reticilerinin istemeden yanl─▒┼č bilgi yayd─▒klar─▒n─▒ hissediyorum. ─░┼čaret├žiler i├žin "referans" kelimesini kullanmak yerine ba┼čka bir ┼čey kullanm─▒┼člard─▒, dingleberry diyelim, sorun olmazd─▒. "Java dingleberry'leri referans olarak de─čil de─čerine g├Âre ge├žirir" diyebilir ve hi├ž kimsenin kafas─▒ kar─▒┼čmaz. (Bundan dolay─▒, referansa g├Âre de─čeri referansla iletirken referanslara dinglebarries olarak at─▒fta bulunaca─č─▒m.)

Sadece Java geli┼čtiricilerinin bu konuda sorunu olmas─▒n─▒n nedeni budur. "Referans" kelimesine bakarlar ve bunun ne anlama geldi─čini tam olarak bildiklerini san─▒rlar, bu y├╝zden kar┼č─▒t tart─▒┼čmay─▒ d├╝┼č├╝nmeye bile zahmet etmiyorlar.

Her neyse, dhackner'in daha ├Ânce sevdi─čim bir balon benzetmesi yapan eski bir yaz─▒daki bir yorumunu fark ettim . O kadar ki, bir miktar k├╝├ž├╝k resmi bir araya getirmek i├žin bir dizi ├žizgi ├žizmeye karar verdim.

Bir referans─▒n de─čerine g├Âre iletilmesi - Referanstaki de─či┼čiklikler arayan─▒n kapsam─▒na yans─▒mamaktad─▒r, ancak nesnedeki de─či┼čiklikler vard─▒r. Bunun nedeni referans─▒n kopyalanmas─▒d─▒r, ancak hem orijinal hem de kopya ayn─▒ nesneye ba┼čvurur.
Nesne ba┼čvurular─▒n─▒ de─čere g├Âre ge├žirmek

Referansa g├Âre ilet - Referans─▒n bir kopyas─▒ yok. Tek referans, hem arayan hem de aranan i┼člev taraf─▒ndan payla┼č─▒l─▒r. Referansta veya Nesne'nin verilerinde yap─▒lacak herhangi bir de─či┼čiklik arayan─▒n kapsam─▒na yans─▒r.
Referans taraf─▒ndan ge├žmek

EDIT 4

Java ile ge├žen parametrenin d├╝┼č├╝k d├╝zeyde uygulanmas─▒n─▒ tan─▒mlayan, harika ve ├žok yararl─▒ oldu─čunu d├╝┼č├╝nd├╝─č├╝m, soyut bir fikri somutla┼čt─▒rd─▒─č─▒ i├žin bu konuyla ilgili yaz─▒lar g├Ârd├╝m. Ancak, bana g├Âre soru, dil spesifikasyonunda a├ž─▒klanan davran─▒┼čla ilgili davran─▒┼č─▒n teknik olarak uygulanmas─▒ndan daha fazlad─▒r. Bu, Java Dil Belirtimi, b├Âl├╝m 8.4.1'den bir al─▒nt─▒d─▒r :

Y├Ântem veya kurucu ├ža─čr─▒ld─▒─č─▒nda (┬ž15.12), ger├žek arg├╝man ifadelerinin de─čerleri , y├Ântemin veya kurucunun g├Âvdesinin y├╝r├╝t├╝lmesinden ├Ânce, bildirilen t├╝rlerin her biri yeni olu┼čturulan parametre de─či┼čkenlerini ba┼člat─▒r. Beyannamede g├Âr├╝nen Tan─▒mlay─▒c─▒, bi├žimsel parametreye ba┼čvurmak i├žin y├Ântemin veya yap─▒c─▒n─▒n g├Âvdesinde basit bir ad olarak kullan─▒labilir.

Bunun anlam─▒, java, bir metodu uygulamadan ├Ânce ge├žen parametrelerin bir kopyas─▒n─▒ yarat─▒r. ├ťniversitedeki derleyicileri alan ├žo─ču insan gibi ben de derleyicilerin kitab─▒ olan ÔÇťThe Dragon BookÔÇŁ ─▒ kulland─▒m . B├Âl├╝m 1'de "De─čerine G├Âre ├ça─čr─▒" ve "Referansa G├Âre ├ça─čr─▒" hakk─▒nda iyi bir a├ž─▒klama vard─▒r. Bu de─čere g├Âre arama a├ž─▒klamas─▒ tam olarak Java Spec ile e┼čle┼čmektedir.

Derleyicileri ald─▒─č─▒mda, kitab─▒n ilk bask─▒s─▒n─▒ 1986'dan, Java'y─▒ 9 ya da 10 y─▒l ├Âncesine dayand─▒ran kulland─▒m. Ancak, 2007'den itibaren Java'dan bahseden 2. Eddition'─▒n bir kopyas─▒na rastlad─▒m . "Parametre Ge├ži┼č Mekanizmalar─▒" etiketli B├Âl├╝m 1.6.6, olduk├ža iyi ge├žen bir parametreyi tan─▒mlar. ─░┼čte Java'dan bahseden "De─čere G├Âre ├ça─č─▒r" ba┼čl─▒─č─▒ alt─▒nda bir al─▒nt─▒:

├ça─čr─▒l─▒ de─čerde, ger├žek parametre (ifade ise) de─čerlendirilir veya kopyalan─▒r (de─či┼čken ise). De─čer, ├ža─čr─▒lan prosed├╝r├╝n ilgili formal parametresine ait konuma yerle┼čtirilir. Bu y├Ântem, C ve Java'da kullan─▒l─▒r ve C ++ ile di─čer bir├žok dilde ortak bir se├ženektir.


41







Farkl─▒l─▒k veya belki de eskiden oldu─ču gibi ayn─▒ izlenim alt─▒nda oldu─čumu hat─▒rlad─▒─č─▒m gibi: Java her zaman de─čerlidir. JavaÔÇÖdaki t├╝m nesneler (JavaÔÇÖda, ilkel d─▒┼č─▒nda herhangi bir ┼čey) referanst─▒r. Bu referanslar de─čere g├Âre iletilir.


36







Daha ├Ânce bir├žok insan─▒n bahsetti─či gibi, Java her zaman de─čerinden

Fark─▒ anlaman─▒za yard─▒mc─▒ olacak ba┼čka bir ├Ârnek: ( klasik takas ├Ârne─či ):

 public class Test {
  public static void main(String[] args) {
    Integer a = new Integer(2);
    Integer b = new Integer(3);
    System.out.println("Before: a = " + a + ", b = " + b);
    swap(a,b);
    System.out.println("After: a = " + a + ", b = " + b);
  }

  public static swap(Integer iA, Integer iB) {
    Integer tmp = iA;
    iA = iB;
    iB = tmp;
  }
}
 

Bask─▒lar:

├ľnce: a = 2, b = 3
Sonra: a = 2, b = 3

Bunun nedeni, iA ve iB'nin, iletilen referanslar─▒n ayn─▒ de─čerine sahip yeni yerel referans de─či┼čkenleri olmalar─▒d─▒r (s─▒ras─▒yla a ve b'ye i┼čaret ederler). Bu nedenle, iA veya iB referanslar─▒n─▒ de─či┼čtirmeye ├žal─▒┼čmak sadece yerel kapsamda de─či┼čecek ve bu y├Ântemin d─▒┼č─▒nda de─či┼čmeyecektir.


35







Java'da yaln─▒zca referanslar iletilir ve de─čere g├Âre iletilir:

Java arg├╝manlar─▒n─▒n t├╝m├╝ de─čere g├Âre iletilir (ba┼čvuru, y├Ântem taraf─▒ndan kullan─▒ld─▒─č─▒nda kopyalan─▒r):

─░lkel t├╝rlerde, Java davran─▒┼č─▒ basittir: De─čer, ilkel t├╝r├╝n ba┼čka bir ├Ârne─čine kopyalan─▒r.

Nesneler s├Âz konusu oldu─čunda, bu ayn─▒d─▒r: Nesne de─či┼čkenleri, yaln─▒zca "yeni" anahtar s├Âzc├╝─č├╝ kullan─▒larak olu┼čturulan ve ilkel t├╝rler gibi kopyalanan Nesnenin adresini tutan i┼čaret├žilerdir (kovalar) .

Davran─▒┼č ilkel t├╝rlerden farkl─▒ g├Âr├╝nebilir: Kopyalanan nesne de─či┼čkeni ayn─▒ adresi (ayn─▒ Nesneye) i├žerdi─činden. Nesnenin i├žeri─či / ├╝yeleri , bir y├Ântem i├žinde hala de─či┼čtirilebilir ve daha sonra d─▒┼čar─▒dan eri┼čerek, (i├žeren) Nesnenin kendisinin referans olarak ge├žirildi─či yan─▒lsamas─▒n─▒ verir.

"String" Nesneler , "Nesneler referans taraf─▒ndan iletiliyor" diyerek ┼čehir efsanesine m├╝kemmel bir kar┼č─▒ ├Ârnek gibi g├Âr├╝nmektedir :

Asl─▒nda, arg├╝man olarak iletilen bir String de─čerini g├╝ncellemek i├žin hi├žbir zaman bir y├Ântemde yapamazs─▒n─▒z:

Bir Dize Nesnesi, karakterleri de─či┼čtirilemeyen bir final olarak bildirilen bir dizi ile tutar . Nesnenin adresi sadece "new" kullan─▒larak ba┼čka biri ile de─či┼čtirilebilir. De─či┼čkeni g├╝ncellemek i├žin "yeni" kullanmak, de─či┼čken ba┼člang─▒├žta de─čere g├Âre ge├žilip kopyaland─▒─č─▒ndan Nesneye d─▒┼čar─▒dan eri┼čilmesine izin vermez.


35







Java sadece de─čere g├Âre ge├žmi┼čtir. Bunu do─črulamak i├žin ├žok basit bir ├Ârnek.

 public void test() {
    MyClass obj = null;
    init(obj);
    //After calling init method, obj still points to null
    //this is because obj is passed as value and not as reference.
}
private void init(MyClass objVar) {
    objVar = new MyClass();
}
 

31







Her zaman "kopya ile ge├ž" olarak d├╝┼č├╝n├╝r├╝m. ─░lkel ya da referans olsun, de─čerin bir kopyas─▒d─▒r. ─░lkel ise, de─čer olan bitlerin bir kopyas─▒d─▒r ve e─čer bir Nesne ise referans─▒n bir kopyas─▒d─▒r.

 public class PassByCopy{
    public static void changeName(Dog d){
        d.name = "Fido";
    }
    public static void main(String[] args){
        Dog d = new Dog("Maxx");
        System.out.println("name= "+ d.name);
        changeName(d);
        System.out.println("name= "+ d.name);
    }
}
class Dog{
    public String name;
    public Dog(String s){
        this.name = s;
    }
}
 

Java PassByCopy ├ž─▒kt─▒s─▒:

name = Maxx
ad─▒ = Fido

─░lkel sarmalay─▒c─▒ s─▒n─▒flar─▒ ve Dizeleri de─či┼čmez oldu─čundan, bu t├╝rlerin kullan─▒ld─▒─č─▒ hi├žbir ├Ârnek di─čer t├╝r / nesnelerle ayn─▒ ┼čekilde ├žal─▒┼čmaz.


29







Buradaki herhangi bir programlama dili i├žin bu t├╝r sorulara ayr─▒lm─▒┼č bir konu yaratt─▒m .https://stackoverflow.com/questions/2027/pass-by-reference-or-pass-by-value

Java da s├Âz edilir . ─░┼čte k─▒sa ├Âzeti:

  • Java, parametrelere de─čere g├Âre ge├žer
  • "de─čere g├Âre", java'da bir y├Ântemi bir parametreye ge├žirmenin tek yoludur
  • parametre olarak verilen nesnedeki y├Ântemleri kullanmak, nesneyi referanslar─▒n orijinal nesnelere i┼čaret etti─či ┼čekilde de─či┼čtirecektir. (bu y├Ântemin kendisi baz─▒ de─čerleri de─či┼čtirirse)

25







Baz─▒ yay─▒nlarda yap─▒lan birka├ž d├╝zeltme.

C referans yoluyla ge├žmeyi desteklemez. HER ZAMAN de─čere g├Âre ge├žer. C ++ ba┼čvuruya g├Âre ge├ži┼či destekliyor, ancak varsay─▒lan de─čil ve olduk├ža tehlikeli.

De─čerin Java'da ne oldu─ču ├Ânemli de─čildir: ilkel veya nesnenin adresi (kabaca), her zaman de─čerine g├Âre iletilir.

E─čer bir Java nesnesi referans olarak ge├žiyormu┼č gibi davran─▒rsa, bu bir de─či┼čkenlik ├Âzelli─čidir ve kesinlikle ge├ži┼č mekanizmalar─▒yla ilgisi yoktur.

Bunun neden bu kadar kafa kar─▒┼čt─▒r─▒c─▒ oldu─čundan emin de─čilim, belki de pek ├žok Java "programc─▒s─▒" resmi olarak e─čitilmedi─činden ve dolay─▒s─▒yla bellekte ger├žekte neler olup bitti─čini anlamad─▒─č─▒n─▒zdan emin de─čilim.


25







Uzun laf─▒n k─▒sas─▒, Java nesnelerinin baz─▒ tuhaf ├Âzelliklere sahip olmas─▒.

Genel olarak, bir Java (ilkel t├╝rleri vard─▒r int , bool , char , double de─čeri do─črudan ge├žirilir, vb). Sonra Java nesneler (t├╝retilen her ┼čey java.lang.Object ) vard─▒r. Nesneler asl─▒nda her zaman bir referansla i┼členir (referans, dokunamad─▒─č─▒n─▒z bir i┼čaret├židir). Bu, referanslar─▒n normalde ilgin├ž olmad─▒─č─▒ i├žin asl─▒nda, nesnelerin referans yoluyla iletildi─či anlam─▒na gelir. Bununla birlikte, referans─▒n de─čeri taraf─▒ndan iletildi─či i├žin hangi nesnenin i┼čaret edildi─čini de─či┼čtiremeyece─činiz anlam─▒na gelir.

Bu ses garip ve kafa kar─▒┼čt─▒r─▒c─▒ m─▒? C uygulamalar─▒n─▒n referans olarak nas─▒l ge├žti─čini ve de─čer olarak nas─▒l ge├žti─čini d├╝┼č├╝nelim. C'de, varsay─▒lan kural de─čere g├Âre iletilir. void foo(int x) int de─čerine g├Âre ge├žer. void foo(int *x) Bir istemeyen bir fonksiyondur int a , ancak bir int i┼čaret├ži: foo(&a) . Biri & de─či┼čken ismini iletmek i├žin operat├Ârle bunu kullan─▒r .

Bunu C ++ 'a g├Ât├╝r, referanslar─▒m─▒z var. Referanslar temel olarak (bu ba─člamda) denklemin imle├ž k─▒sm─▒n─▒ gizleyen s├Âzdizimsel ┼čekerdir: void foo(int &x) denir foo(a) , burada derleyicinin bir referans oldu─čunu ve referans olmayan─▒n adresinin ge├žilmesi a gerekti─čini bilir . Java'da, nesnelere at─▒fta bulunan t├╝m de─či┼čkenler asl─▒nda referans t├╝r├╝ndedir; ├Ârne─čin, C ++ taraf─▒ndan sa─članan ince taneli kontrol (ve karma┼č─▒kl─▒k) olmadan ├žo─ču ama├ž ve ama├ž i├žin ├ža─čr─▒ya g├Âre ├ža─čr─▒ya zorlama.


23