ජාවා “පසු-යොමු කිරීම” හෝ “පසු-අගය” ද?


6584

මම නිතරම සිතුවේ ජාවා සම්මතයෙන් යොමු කිරීමක් බවයි.

කෙසේ වෙතත්, එය එසේ නොවන බව පවසන බ්ලොග් සටහන් කිහිපයක් (උදාහරණයක් ලෙස, මෙම බ්ලොගය ) මම දැක ඇත්තෙමි .

මම හිතන්නේ නැහැ ඔවුන් කරන වෙනස මට තේරෙනවා කියලා.

පැහැදිලි කිරීම කුමක්ද?


706
මෙම ප්‍රශ්නය පිළිබඳ බොහෝ ව්‍යාකූලත්වයට විවිධ පුද්ගලයින්ට “යොමු” යන යෙදුමට විවිධ අර්ථකථන ඇති බව මම විශ්වාස කරමි. C ++ පසුබිමකින් පැමිණෙන පුද්ගලයින් උපකල්පනය කරන්නේ "යොමු කිරීම" යන්නෙන් අදහස් කරන්නේ C ++ යන්නෙන් අදහස් වන බවයි, C පසුබිමක සිටින අය උපකල්පනය කරන්නේ "යොමු කිරීම" ඔවුන්ගේ භාෂාවේ "දර්ශකය" හා සමාන විය යුතු බවයි. ජාවා යොමු කිරීම හරහා ගමන් කරන බව පැවසීම නිවැරදිද යන්න සැබවින්ම රඳා පවතින්නේ "යොමු" යන්නෙන් අදහස් කරන දේ මතය.
ගුරුත්වාකර්ෂණය

119
ඇගයීම් උපාය මාර්ග ලිපියේ ඇති පාරිභාෂිතය නිරන්තරයෙන් භාවිතා කිරීමට මම උත්සාහ කරමි . එය කොන්දේසි සිදු ලිපිය ලකුණු ප්රජාව විසින් විශාල වශයෙන් වෙනස් වුවද, එය, බව සඳහන් කළ යුතු ය සඳහා semantics බව අවධාරණය call-by-valueහා call-by-referenceඉතා තීරණාත්මක ආකාරයෙන් වෙනස් . (පෞද්ගලිකව භාවිතා කිරීමට මම කැමති call-by-object-sharingපුරා මේ දින call-by-value[-of-the-reference], මෙම ඉහළ මට්ටමින් semantics විස්තර හා සමග ගැටුම් ඇති නොවන ලෙස call-by-valueකරන, යටින් පවත්නා ක්රියාත්මක කිරීම.)

59
Ra ගුරුත්වාකර්ෂණය: ඔබට ගොස් ඔබේ අදහස් විශාල දැන්වීම් පුවරුවකට හෝ වෙනත් දෙයකට තැබිය හැකිද? කෙටියෙන් එය සමස්ත ප්‍රශ්නයයි. තවද එය පෙන්නුම් කරන්නේ මේ සියල්ලම අර්ථ නිරූපණයන් බවයි. යොමු
කිරීමක

30
මම හිතන්නේ ව්‍යාකූලත්වය “යොමු යොමු අර්ථකථනය” හා එදිරිව “යොමු කිරීම” යන්නයි. ජාවා යනු යොමු අර්ථ නිරූපණයන් සමඟ අගය-අගයයි.
spraff

11
@Gravity, ඔබ ඉන්නේ අතර පරම C ++ සිට පැමිණෙන බව ජනතාවට දැනෙන නිවැරදි ඉවෙන් මෙන් "සඳහන්" යන වචනය සම්බන්ධයෙන් වෙනස් දෙබස් කවන ශිල්පීනියක කට්ටලයක්, මම පෞද්ගලිකව සිරුර "මගින්" වඩාත් තැන්පත් විශ්වාස කරනු ඇත. "Pass by" අවුල් සහගත වන්නේ එය ජාවා හි "Passing a" ට වඩා සම්පූර්ණයෙන්ම වෙනස් බවය. C ++ හි කෙසේ වෙතත් එය වාචිකව නොවේ. C ++ හි ඔබට "යොමු කිරීමක් සම්මත කිරීම" යැයි පැවසිය හැකිය, එය පරීක්ෂණයෙන් සමත් වන බව වටහාගෙන ඇතswap(x,y) .

Answers:


5846

ජාවා සෑම විටම අගය අනුව ය . අවාසනාවකට මෙන්, අප යම් වස්තුවක වටිනාකම පසු කරන විට, අපි ඒ වෙත යොමු කිරීම සිදු කරන්නෙමු. මෙය ආරම්භකයින්ට ව්‍යාකූල වේ.

එය මෙසේ ය:

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
}

ඉහත උදාහරණයේ දී aDog.getName()තවමත් නැවත පැමිණේ "Max". වටිනාකම aDogඇතුළත mainමෙම උත්සවයට වෙනස් නොවේ fooසමග Dog "Fifi"වස්තුව යොමු අගය විසින් සම්මත කෙරෙනු ඇත. එය සඳහන් විසින් සම්මත කරන ලදී නම්, aDog.getName()දී mainඇති බවත් නැවත "Fifi"කිරීමට ඇමතුමක් පසු foo.

එලෙසම:

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");
}

ඉහත උදාහරණයේ දී, Fifiඇමතුමෙන් පසු බල්ලාගේ නම foo(aDog)වන්නේ වස්තුවේ නම ඇතුලත සකසා ඇති foo(...)බැවිනි. ඕනෑම මෙහෙයුම් fooපිළිබඳ කාර්ය ඉටු dසියලු ම ප්රායෝගික අරමුණු සඳහා, ඔවුන් මත සිදු කෙරෙන බව එම වේ aDog, නමුත් ඒ නොහැකි විචල්ය අගය වෙනස් කිරීමට හැකි aDogම.


263
අභ්‍යන්තර තොරතුරු සමඟ ගැටළුව තරමක් ව්‍යාකූල නොවේ ද? ඔබ අදහස් කරන්නේ 'වස්තුවට අභ්‍යන්තර දර්ශකයේ වටිනාකම' යැයි උපකල්පනය කරමින්, 'යොමු කිරීමක් පසු කිරීම' සහ 'යොමුවක වටිනාකම පසු කිරීම' අතර සංකල්පමය වෙනසක් නොමැත.
izb

383
නමුත් සියුම් වෙනසක් ඇත. පළමු උදාහරණය දෙස බලන්න. එය තනිකරම යොමු කිරීමකින් නම්, aDog.name "Fifi" වේ. එය එසේ නොවේ - ඔබට ලැබෙන යොමු කිරීම අගය යොමු කිරීමක් වන අතර එය ශ්‍රිතයෙන් පිටවන විට නැවත ලිවීම ප්‍රතිෂ් will ාපනය වේ.
erlando

300
Ore ලොරෙන්සෝ: නැත, ජාවා හි සෑම දෙයක්ම වටිනාකමින් සම්මත වේ. ප්‍රාථමිකයන් අගය මගින් සම්මත වන අතර වස්තු යොමු කිරීම් අගය මගින් සම්මත වේ. වස්තූන් කිසි විටෙකත් ක්‍රමයකට යොමු නොකෙරේ, නමුත් වස්තූන් සැමවිටම ගොඩවල පවතින අතර එම ක්‍රමයට වස්තුව පිළිබඳ සඳහනක් පමණක් ලබා දේ.
Esko Luontola

295
වස්තුව පසු කිරීම දෘශ්‍යමාන කිරීමට හොඳ ක්‍රමයක් සඳහා මගේ උත්සාහය: බැලූනයක් ගැන සිතන්න. Fxn ඇමතීම හරියට බැලූනයකට දෙවන නූලක් බැඳ fxn වෙත රේඛාව භාර දීම හා සමානයි. පරාමිතිය = නව බැලූනය () එම නූල කපා නව බැලූනයක් නිර්මාණය කරයි (නමුත් මෙය මුල් බැලූනයට කිසිදු බලපෑමක් නොකරයි). param.pop () තවමත් එය මුල් පිටපතට යොමු කරයි. ජාවා අගය අනුව ගමන් කරයි, නමුත් සම්මත අගය ගැඹුරු නොවේ, එය ඉහළම මට්ටමේ පවතී, එනම් ප්‍රාථමික හෝ දර්ශකයක්. වස්තුව මුළුමනින්ම ක්ලෝන කර සම්මත කර ඇති ගැඹුරු පාස්-බයි-අගය සමඟ එය පටලවා නොගන්න.
dhackner

150
ව්යාකූල වන්නේ වස්තු යොමු කිරීම් ඇත්ත වශයෙන්ම දර්ශකයන් වීමයි. ආරම්භයේ දී SUN ඒවා යොමු කරන්නන් ලෙස හැඳින්වීය. එවිට අලෙවිකරණය දැනුම් දුන්නේ "දර්ශකය" නරක වචනයක් බවයි. නමුත් ඔබ තවමත් NullPointerException හි "නිවැරදි" නාමකරණය දකී.
මහාචාර්ය ෆැල්කන් කොන්ත්‍රාත්තුව

3036

මම දැක්කා ඔබ මගේ ලිපිය යොමු කර ඇති බව .

ජාවා පිරිවිතරයන් පවසන්නේ ජාවා හි ඇති සෑම දෙයක්ම වටිනාකමින් යුතු බවයි. ජාවා හි "පාස්-බයි-යොමු" වැනි දෙයක් නොමැත.

මෙය තේරුම් ගැනීමේ යතුර නම් එවැනි දෙයක්

Dog myDog;

නොවන බල්ලෙක්; එය ඇත්ත වශයෙන්ම බල්ලෙකුට යොමු කිරීමකි.

එහි තේරුම, ඔබ සිටින විට ය

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

ඔබ මූලිකවම නිර්මාණය කරන ලද වස්තුවෙහි ලිපිනය ක්‍රමයට Dogයවනු ලැබේ foo.

(මම මූලිකවම කියන්නේ ජාවා පොයින්ටර්ස් සෘජු ලිපින නොවන නිසා නමුත් ඒවා එසේ සිතීම පහසුය)

Dogවස්තුව මතක ලිපිනය 42 හි ඇතැයි සිතමු. මෙයින් අදහස් කරන්නේ අපි ක්‍රමයට 42 පසු කරන බවයි.

ක්‍රමය අර්ථ දක්වා ඇත්නම්

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

සිදුවන්නේ කුමක්දැයි බලමු.

  • පරාමිතිය someDog42 අගයට සකසා ඇත
  • "AAA" පේළියේ
    • someDogඑය යොමු කරන Dogස්ථානයට අනුගමනය කරනු ලැබේ ( Dogලිපිනය 42 හි ඇති වස්තුව)
    • බව Dog(ලිපිනය 42 දී එක්) උපරිම ඔහුගේ නම වෙනස් කිරීමට ඉල්ලා ඇත
  • "BBB" පේළියේ
    • නව Dogඑකක් නිර්මාණය වේ. ඔහු 74 වන ලිපිනයේ සිටින බව කියමු
    • අපි පරාමිතිය someDog74 ට පවරමු
  • "CCC" පේළියේ
    • someDog එය යොමු කරන ස්ථානයට අනුගමනය කරයි Dog( Dogලිපිනය 74 හි ඇති වස්තුව)
    • බව Dog(ලිපිනය 74 ක් එක්) Rowlf ඔහුගේ නම වෙනස් කිරීමට ඉල්ලා ඇත
  • ඊටපස්සේ අපි ආපහු එනවා

දැන් ක්‍රමයෙන් පිටත සිදුවන්නේ කුමක්ද යන්න ගැන සිතා බලමු:

කළ myDogවෙනස්?

යතුර තියෙනවා.

මතක තබා ගනිමින් බව myDogකියන්නේ පහිටුම් දක්වනය සත්ය නොව, Dogඑම පිළිතුර නැත යන්නයි. myDogතවමත් වටිනාකම 42; එය තවමත් මුල් පිටපතට යොමු වෙමින් පවතී Dog(නමුත් "AAA" රේඛාව නිසා එහි නම දැන් "මැක්ස්" - තවමත් එකම බල්ලාගේ myDogවටිනාකම වෙනස් වී නැති බව සලකන්න .)

ලිපිනයක් අනුගමනය කිරීම සහ එහි අවසානයේ ඇති දේ වෙනස් කිරීම සම්පූර්ණයෙන්ම වලංගු වේ ; කෙසේ වෙතත් එය විචල්‍යය වෙනස් නොකරයි.

ජාවා හරියටම සී මෙන් ක්‍රියා කරයි. ඔබට දර්ශකයක් පැවරිය හැකිය, දර්ශකය ක්‍රමයකට යොමු කළ හැකිය, ක්‍රමයේ දර්ශකය අනුගමනය කර පෙන්වා දුන් දත්ත වෙනස් කළ හැකිය. කෙසේ වෙතත්, එම දර්ශකය යොමු වන ස්ථානය ඔබට වෙනස් කළ නොහැක.

C ++, Ada, Pascal සහ වෙනත් භාෂා වලින් යොමු කිරීම සඳහා සහය දක්වන, ඔබට සම්මත කළ විචල්‍යය සැබවින්ම වෙනස් කළ හැකිය.

ජාවාට පාස්-බයි-යොමු අර්ථකථන තිබුනේ නම්, fooඅප ඉහත අර්ථ දක්වා ඇති ක්‍රමය බීබීබී රේඛාවට myDogපවරා someDogඇති විට එය යොමු වන ස්ථානය වෙනස් වීමට ඉඩ තිබුණි .

යොමු පරාමිතීන් සම්මත විචල්‍යය සඳහා අන්වර්ථයක් ලෙස සිතන්න. එම අන්වර්ථය පවරා ඇති විට, විචල්‍යය ද සම්මත විය.


164
"ජාවාහි දර්ශකයන් නොමැත" යන පොදු වැලකී සිටීම එතරම් නොමඟ යවන්නේ මේ නිසා ය.
බෙස්කා

135
ඔයා වැරදියි, ඉමෝ. "MyDog යනු දර්ශකයක් මිස සැබෑ බල්ලෙකු නොවන බව මතක තබා ගනිමින් පිළිතුර නැත. MyDog ට තවමත් 42 වන අගය ඇත; එය තවමත් මුල් බල්ලා වෙත යොමු කරයි." myDog හි වටිනාකම 42 වන නමුත් එහි නම තර්කයේ දැන් // AAA රේඛාවේ "රෝවර්" වෙනුවට "මැක්ස්" අඩංගු වේ.
Özgür

180
මේ ගැන සිතන්න. "AnnArborLocation" නමින් හැඳින්වෙන කඩදාසි පෙත්තක් මත Ar න් ආබර්, එම්අයි (මගේ උපන් නගරය, GO BLUE!) හි ලිපිනයක් ඇත. ඔබ එය "myDestination" නමින් කඩදාසි කැබැල්ලක පිටපත් කරන්න. ඔබට "myDestination" වෙත ගොස් ගසක් සිටුවිය හැකිය. ඔබ එම ස්ථානයේ නගරය ගැන යමක් වෙනස් කර ඇති නමුත් එය කඩදාසි දෙකකින් ලියා ඇති LAT / LON වෙනස් නොකරයි. ඔබට "myDestination" හි LAT / LON වෙනස් කළ හැකි නමුත් එය "annArborLocation" වෙනස් නොකරයි. එය උපකාරවත් වේද?
ස්කොට් ස්ටැන්ච්ෆීල්ඩ්

43
C ස්කොට් ස්ටැන්ච්ෆීල්ඩ්: මම මීට වසරකට පමණ පෙර ඔබේ ලිපිය කියවූ අතර එය මට කරුණු පැහැදිලි කිරීමට උපකාරී විය. ස්තූතියි! මම නිහතමානීව කුඩා එකතු කිරීමක් යෝජනා කරමි: බාබරා ලිස්කොව් විසින් ඇගේ සීඑල්යූ භාෂාවේ ඇගයීමේ උපායමාර්ගය විස්තර කිරීම සඳහා සොයා ගන්නා ලද “අගය අනුව ඇමතුමක වටිනාකම” යන්න විස්තර කරන නිශ්චිත යෙදුමක් ඇත්ත වශයෙන්ම ඇති බව ඔබ සඳහන් කළ යුතුය. 1974, ඔබේ ලිපිය ආමන්ත්‍රණය කිරීම වැනි ව්‍යාකූලතාවයන් වළක්වා ගැනීම සඳහා: බෙදාගැනීමෙන් අමතන්න (සමහර විට වස්තු හුවමාරුවෙන් ඇමතුමක් හෝ වස්තුවකින් ඇමතුමක් ලෙස හැඳින්වේ ), එය අර්ථ නිරූපණයන් මනාව විස්තර කරයි.
ජෝර්ග් ඩබ් මිට්ටාග්

29
E ගීවෝර්ග් - සී / සී ++ භාෂාවන්ට “දර්ශකය” යන සංකල්පය හිමි නොවේ. දර්ශක භාවිතා කරන වෙනත් භාෂාවන් ඇත, නමුත් C / C ++ ඉඩ දෙන එකම ආකාරයේ දර්ශක හැසිරවීමට ඉඩ නොදෙන්න. ජාවා දර්ශකයන් ඇත; ඔවුන් හුදෙක් අකටයුතුකම් වලින් ආරක්ෂා වී ඇත.
ස්කොට් ස්ටැන්ච්ෆීල්ඩ්

1741

ජාවා සැමවිටම තර්ක ඉදිරිපත් කරන්නේ අගය අනුව මිස යොමු කිරීමකින් නොවේ.


මෙය උදාහරණයක් මගින් පැහැදිලි කිරීමට මට ඉඩ දෙන්න :

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");
     }

}

මම මෙය පියවරෙන් පියවර පැහැදිලි කරමි:

  1. fවර්ගය නම් කරන ලද යොමු කිරීමක් ප්‍රකාශ කර එය ගුණාංගයක් Fooසහිත නව වස්තුවක් පවරන්න .Foo"f"

    Foo f = new Foo("f");

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  2. ක්‍රමයේ පැත්තෙන්, Fooනමක් සහිත වර්ගයක් පිළිබඳ සඳහනක් aප්‍රකාශයට පත් කරන අතර එය මුලින් පවරා nullඇත.

    public static void changeReference(Foo a)

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  3. ඔබ ක්‍රමවේදය අමතන්නාක් මෙන් changeReference, යොමු aකිරීමක් තර්කයක් ලෙස සම්මත කරන ලද වස්තුව පවරනු ලැබේ.

    changeReference(f);

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  4. bවර්ගය නම් කරන ලද යොමු කිරීමක් ප්‍රකාශ කර එය ගුණාංගයක් Fooසහිත නව වස්තුවක් පවරන්න .Foo"b"

    Foo b = new Foo("b");

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  5. a = bසමුද්දේශ නව පැවරුම කරයි a, නැති f , කාගේ එහි ලක්ෂණයට වස්තුවේ "b".

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  6. ඔබ modifyReference(Foo c)ක්‍රමයට කතා කරන විට , යොමු cකිරීමක් නිර්මාණය කර ඇති අතර එය වස්තුවට ආරෝපණය කර "f"ඇත.

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

  7. c.setAttribute("c");cඑය යොමු කරන වස්තුවෙහි ගුණාංගය වෙනස් කරනු ඇති අතර එය යොමු කරන fවස්තුවම වේ.

    රූප විස්තරය මෙහි ඇතුළත් කරන්න

ජාවා හි තර්ක ලෙස වස්තූන් ගමන් කරන ආකාරය දැන් ඔබට වැටහෙනු ඇතැයි මම බලාපොරොත්තු වෙමි :)


82
+1 ලස්සන දේවල්. හොඳ රූප සටහන්. මම මෙහි හොඳ සාරාංශ පිටුවක් ද සොයා ගතිමි adp-gmbh.ch/php/pass_by_reference.html හරි එය PHP හි ලියා ඇති බව මම පිළිගනිමි, නමුත් එය වැදගත් යැයි මා සිතන වෙනස තේරුම් ගැනීමේ මිල වේ (සහ එම වෙනස හසුරුවන්නේ කෙසේද? ඔබේ අවශ්‍යතා).
ඩේව්එම්

5
Eng.Fouad ඒක ලස්සන පැහැදිලි කිරීමක් නොව නම් @ aඑම වස්තුව වෙත කරුණු ලෙස f(වස්තුව තමන්ගේ ම පිටපතක් ලැබෙන හා කවදාවත් fලකුණු කිරීම සඳහා), වස්තුව යම් වෙනස් භාවිතා කළ aවෙනස් කළ යුතු f(මේ දෙකෙන්ම එකම වස්තුව සමඟ වැඩ සිටින නිසා aswell ), එබැවින් යම් අවස්ථාවක දී වස්තු ලක්ෂ්‍යවල aතමන්ගේම පිටපතක් ලබා ගත යුතුය f.
0x6C38

14
A 'm' එකම වස්තුවකට 'f' පෙන්වා දෙන විට, 'a' හරහා එම වස්තුවට කරන ඕනෑම වෙනසක් 'f' හරහා ද නිරීක්ෂණය කළ හැකි නමුත් එය 'f' වෙනස් නොකළේය. 'f' තවමත් එකම වස්තුවට යොමු කරයි. ඔබට වස්තුව මුළුමනින්ම වෙනස් කළ හැකිය, නමුත් ඔබට කිසි විටෙකත් 'f' පෙන්වා දෙන දේ වෙනස් කළ නොහැක. කිසියම් හේතුවක් නිසා සමහර අයට තේරුම් ගත නොහැකි මූලික කාරණය මෙයයි.
මයික් බ්‍රවුන්

Ike මයික් බ්‍රවුන් ... මොකක්ද? දැන් ඔබ මාව ව්‍යාකූල කළා: එස්. ඔබ දැන් ලියා ඇති දේ 6 සහ 7 පෙන්වන දෙයට පටහැනි නොවේද?
නපුරු රෙදි සෝදන යන්ත්‍රය

6
මම සොයාගත් හොඳම පැහැදිලි කිරීම මෙයයි. මාර්ගය වන විට, මූලික තත්වය ගැන කුමක් කිව හැකිද? උදාහරණයක් ලෙස, තර්කයට int වර්ගයක් අවශ්‍ය වේ, එය තවමත් int විචල්‍යයක පිටපත තර්කයට යොමු කරයිද?
ඇලන්වාන්ග්

733

මෙය ජාවා සැබවින්ම ක්‍රියා කරන ආකාරය පිළිබඳ යම් අවබෝධයක් ලබා දෙනු ඇත, ජාවා ගැන ඔබේ ඊළඟ සාකච්ඡාවේදී යොමු කිරීම හෝ අගය අනුව ගමන් කිරීම ගැන ඔබ සිනාසෙනු ඇත :-)

පළමු පියවර කරුණාකර ඔබේ මනසින් මකා දමන්න 'p' "_ _ _ _ _ _ _", විශේෂයෙන් ඔබ වෙනත් ක්‍රමලේඛන භාෂාවලින් පැමිණෙන්නේ නම්. ජාවා සහ 'පී' එකම පොතක, සංසදයක හෝ ටෙක්ස්ට් එකක ලිවිය නොහැක.

දෙවන පියවර මතක තබා ගන්න ඔබ වස්තුවක් ක්‍රමයකට යොමු කරන විට ඔබ වස්තු යොමු කිරීම මිස වස්තුවම නොවන බව.

  • ශිෂ්‍යයා : මාස්ටර්, මෙයින් අදහස් කරන්නේ ජාවා පාස්-බයි-යොමු කිරීමක් බවද?
  • මාස්ටර් : තණකොළ, නැත.

දැන් සිතන්න වස්තුවක යොමු / විචල්‍යය / කරන්නේ කුමක්ද:

  1. විචල්‍යයක් මඟින් යොමු කරන ලද වස්තුව මතකයේ (Heap) වෙත ළඟා වන්නේ කෙසේදැයි JVM ට පවසන බිටු රඳවා තබා ගනී.
  2. ක්‍රමයකට තර්ක ඉදිරිපත් කිරීමේදී ඔබ යොමු විචල්‍යය පසුකරන්නේ නැත, නමුත් යොමු විචල්‍යයේ බිටු වල පිටපතකි . මේ වගේ දෙයක්: 3bad086a. 3bad086a නිරූපණය කරන්නේ සම්මත වස්තුව වෙත ළඟා වීමේ මාර්ගයකි.
  3. එබැවින් ඔබ 3bad086a පසුකරන්නේ එය යොමු කිරීමේ වටිනාකම බව ය.
  4. ඔබ යොමු කරන්නේ යොමු කිරීමේ වටිනාකම මිස යොමු කිරීම නොවේ (වස්තුව නොවේ).
  5. මෙම අගය ඇත්ත වශයෙන්ම COPIED කර ක්‍රමයට ලබා දී ඇත .

පහත දැක්වෙන පරිදි (කරුණාකර මෙය සම්පාදනය කිරීමට / ක්‍රියාත්මක කිරීමට උත්සාහ නොකරන්න ...):

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. }

සිදුවන්නේ කුමක් ද?

  • විචල්ය පුද්ගලයා # 1 පේළියේ නිර්මාණය කර ඇති අතර එය ආරම්භයේදීම ශුන්‍ය වේ.
  • නව පුද්ගල වස්තුවක් # 2 පේළියේ නිර්මාණය කර ඇති අතර එය මතකයේ ගබඩා කර ඇති අතර විචල්‍ය පුද්ගලයාට පුද්ගල වස්තුව වෙත යොමු කිරීමක් ලබා දේ. එනම් එහි ලිපිනයයි. 3bad086a කියමු.
  • වස්තුවෙහි ලිපිනය රඳවා ඇති විචල්‍ය පුද්ගලයා # 3 පේළියේ ශ්‍රිතයට ලබා දෙනු ලැබේ.
  • # 4 වන පේළියේ ඔබට නිශ්ශබ්දතාවයේ ශබ්දයට සවන් දිය හැකිය
  • # 5 වන පේළියේ අදහස පරීක්ෂා කරන්න
  • දේශීය විචල්ය ක්‍රමයක් - anotherReferenceToTheSamePersonObject - නිර්මාණය කර # 6 වන පේළියේ මැජික් පැමිණේ:
    • විචල්ය / යොමු පුද්ගලයා බිට්-බිට් පිටපත් කර ශ්‍රිතය තුළ වෙනත් යොමු යොමු ටෝසෙම්පර්සන් ඕබෙක්ට් වෙත යවනු ලැබේ.
    • පුද්ගලයාගේ නව අවස්ථා කිසිවක් නිර්මාණය නොවේ.
    • " පුද්ගලයා " සහ "වෙනත් රෙෆරෙන්ටෝසෙම්පර්සන් ඕබෙක්ට් " යන දෙකම 3bad086a හි සමාන අගයක් දරයි.
    • මෙය උත්සාහ නොකරන්න, නමුත් පුද්ගලයා == තවත් යොමු කිරීමක් ToSamePersonObject සත්‍ය වනු ඇත.
    • විචල්‍යයන් දෙකෙහිම යොමු කිරීමේ හැඳුනුම්පත් ඇති අතර ඒවා දෙකම එකම පුද්ගල වස්තුවක් වන අතර, ගොඩේ ඇති එකම වස්තුව සහ කෝපි නොවේ.

පින්තූරයක් වචන දහසක් වටිනවා:

අගය අනුව ගමන් කරන්න

තවත් ReeferenceToTheSamePersonObject ඊතල යොමු වී ඇත්තේ වස්තුව දෙසට මිස විචල්‍ය පුද්ගලයා දෙසට නොවන බව සලකන්න!

ඔබට එය නොලැබුනේ නම්, මාව විශ්වාස කර ජාවා අගය ඉක්මවා යන බව පැවසීම වඩා හොඳ බව මතක තබා ගන්න . හොඳයි, යොමු අගය අනුව සමත් වන්න . ඔහ්, ඊටත් වඩා හොඳ වන්නේ විචල්‍ය-අගය-පිටපත්-පිටපත් කිරීමයි! ;)

දැන් මට වෛර කිරීමට නිදහස්ව සිටින්න, නමුත් මෙය ලබා දී ඇත්තේ ක්‍රම තර්ක ගැන කතා කිරීමේදී ප්‍රාථමික දත්ත වර්ග සහ වස්තු සම්මත කිරීම අතර වෙනසක් නොමැති බව සලකන්න .

ඔබ සැමවිටම යොමු වටිනාකමෙහි බිටු පිටපතක් ලබා දෙයි!

  • එය ප්‍රාථමික දත්ත වර්ගයක් නම්, මෙම බිටු වල ප්‍රාථමික දත්ත වර්ගයේ වටිනාකම අඩංගු වේ.
  • එය වස්තුවක් නම්, ජේවීඑම් වෙත වස්තුව වෙත ළඟා වන්නේ කෙසේදැයි පවසන ලිපිනයේ වටිනාකම බිටු වල අඩංගු වේ.

ජාවා සම්මතයෙන් වටිනාකමක් ඇති නිසා ක්‍රමයක් තුළ ඔබට අවශ්‍ය පරිදි යොමු කරන ලද වස්තුව වෙනස් කළ හැකි නමුත් ඔබ කොතරම් උත්සාහ කළත් ඔබට කිසි විටෙකත් සම්මත විචල්‍යය වෙනස් කිරීමට නොහැකි වනු ඇත, එය යොමු කිරීම දිගටම කරගෙන යනු ඇත (p _ _ _ _ _ _ _) එකම වස්තුව කුමක් වුවත්!


සම්මත කළ යොමුවෙහි සත්‍ය අන්තර්ගතය (බිට් අගයන්) වෙනස් කිරීමට ඉහත වෙනස් කිරීමේ නම ශ්‍රිතයට කිසි විටෙකත් නොහැකි වනු ඇත. වෙනත් වචන වලින් කිවහොත් changeName මගින් පුද්ගලයෙකුට වෙනත් වස්තුවක් වෙත යොමු කළ නොහැක.


ඇත්ත වශයෙන්ම ඔබට එය කෙටි කළ හැකි අතර ජාවා අගය ඉක්මවා යයි කියන්න !


5
ඔබ අදහස් කරන්නේ දර්ශකයන්ද? .. මම එය නිවැරදිව ලබා ගන්නේ නම් public void foo(Car car){ ... }, carඑය දේශීය වන fooඅතර එහි වස්තුවෙහි ගොඩවල් පිහිටීම අඩංගු වේද? ඉතින් මම carඅගය අගය අනුව වෙනස් කළහොත් car = new Car(), එය ගොඩේ විවිධ වස්තුවට යොමු වේ ද? මම carදේපල වටිනාකම අනුව වෙනස් කළහොත් car.Color = "Red", පෙන්වා ඇති ගොඩවල ඇති වස්තුව carවෙනස් කරනු ලැබේ. එසේම, C # හි එය සමානද? කරුණාකර පිළිතුරු දෙන්න! ස්තූතියි!
dpp

11
@domanokz ඔබ මාව මරනවා, කරුණාකර නැවත එම වචනය නොකියන්න! ;) 'යොමු කිරීම' නොකියා මට මෙම ප්‍රශ්නයට පිළිතුරු දිය හැකි බව සලකන්න. එය පාරිභාෂිත ප්‍රශ්නයක් වන අතර එය වඩාත් නරක අතට හැරේ. අවාසනාවකට මා සහ ස්කොට් මේ පිළිබඳව විවිධ අදහස් දරති. මම හිතන්නේ ඔබට එය ජාවා හි ක්‍රියාත්මක වන ආකාරය ලැබී ඇති අතර, දැන් ඔබට එය අගය-අගය, අතුරු-වස්තු-බෙදාගැනීම, විචල්‍ය-වටිනාකමේ පිටපතක් ලෙස හැඳින්විය හැකිය, නැතහොත් වෙනත් දෙයක් ඉදිරිපත් කිරීමට නිදහස්ව සිටින්න! ඔබ එය ක්‍රියාත්මක වන ආකාරය සහ විචල්‍ය වර්ගයේ වස්තුවක් ඇති තාක් කල් මට කමක් නැත: තැ.පෙ. ;)
මාර්සෙලස් වොලස්

9
ඔබ දැන් යොමු කිරීමක් කළා වගේද? ජාවා තවමත් පිටපත් කරන ලද යොමු-භාෂාවක් වන නිසා මම එය ජය ගන්නෙමි. එය පිටපත් කරන ලද සඳහනක් වීම පාරිභාෂිතය වෙනස් නොකරයි. යොමු කිරීම් දෙකම එකම වස්තුවකට යොමු කරයි. මෙය පාරිශුද්ධවාදියෙකුගේ තර්කයක් ...
ජෝන් ස්ට්‍රික්ලර්

3
න්‍යායාත්මක රේඛාව # 9 මතට වැටෙන්නේ System.out.println(person.getName());කුමක් ද? "ටොම්" හෝ "ජෙරී"? මෙම ව්‍යාකූලත්වයට බාධා කිරීමට මට උපකාර වන අවසාන දෙය මෙයයි.
TheBrenny

1
"වටිනාකම සඳහන් " අවසානයේ මට එය පැහැදිලි වන්නේ.
ඇලෙක්සැන්ඩර් ෂුබට්

689

ජාවා සෑම විටම කිසිදු ව්යතිරේකයක්, සමග, වටිනාකම සමත් වේ මෙතෙක් .

ඉතින් ඕනෑම කෙනෙකුට මෙයින් කිසිසේත් ව්‍යාකූල විය හැක්කේ කෙසේද, සහ ජාවා යොමු කිරීමකින් පසු වූවක් යැයි විශ්වාස කරන්නේද, නැතහොත් ජාවා යොමු කිරීමක් ලෙස ක්‍රියා කිරීම පිළිබඳ උදාහරණයක් ඔවුන් සතුව ඇතැයි සිතන්නේද? වැදගත්ම කරුණ නම් , ඕනෑම තත්වයක් තුළ ජාවා කිසි විටෙකත් වස්තූන්ගේ වටිනාකම් වලට access ජු ප්‍රවේශයක් ලබා නොදීමයි. වස්තූන් සඳහා ඇති එකම ප්‍රවේශය එම වස්තුව වෙත යොමු කිරීමකි . ජාවා වස්තූන් නිසා සෑම විටම සැඳහුම හරහා ප්රවේශ, ඒ වෙනුවට සෘජුව වඩා, එය ක්ෂේත්ර සහ විචල්ය ගැන සාකච්ඡාව සඳහා පොදු හා ක්රමය තර්ක ලෙස වස්තූන් , pedantically ඔවුන් පමණක් සිටින විට වස්තූන් යොමු .ව්යාකූලත්වය පැන නගින්නේ මෙම (තදින් කථා කිරීම, වැරදි) නාමකරණය වෙනස් කිරීමෙනි.

එබැවින්, ක්රමයක් ඇමතීමේදී

  • ප්‍රාථමික තර්ක සඳහා ( int,, longආදිය), අගය අනුව ගමන් කිරීම යනු ප්‍රාථමිකයේ සත්‍ය අගයයි (නිදසුනක් ලෙස, 3).
  • වස්තූන් සඳහා, අගය අනුව ගමන් කිරීම යනු වස්තුව වෙත යොමු කිරීමේ වටිනාකමයි .

එබැවින් ඔබ සතුව තිබේ නම් doSomething(foo)සහ public void doSomething(Foo foo) { .. }ෆූස් දෙක එකම වස්තූන් වෙත යොමු වන යොමු පිටපත් කර තිබේ .

ස්වාභාවිකවම, වටිනාකමක් අනුව වස්තුවක් වෙත යොමු කිරීමක් බොහෝ සෙයින් පෙනේ (එය ප්‍රායෝගිකව වෙන් කොට හඳුනාගත නොහැකිය) වස්තුවක් යොමු කිරීමකින් පසු කිරීම.


7
ප්‍රාථමිකයන්ගේ අගයන් වෙනස් කළ නොහැකි බැවින් (නූල් වැනි), අවස්ථා දෙක අතර වෙනස සැබවින්ම අදාළ නොවේ.
Paŭlo Ebermann

4
හරියටම. නිරීක්ෂණය කළ හැකි ජේවීඑම් හැසිරීමෙන් ඔබට පැවසිය හැකි සියල්ල සඳහා, ප්‍රාථමිකයන් යොමු කිරීම මගින් සම්මත කළ හැකි අතර ගොඩවල් මත ජීවත් විය හැකිය. ඒවා එසේ නොවේ, නමුත් එය කිසිඳු ආකාරයකින් නිරීක්ෂණය කළ නොහැකිය.
ගුරුත්වාකර්ෂණය

6
ප්‍රාථමිකයන් වෙනස් කළ නොහැකිද? ජාවා 7 හි එය අලුත්ද?
user85421

4
පොයින්ටර්ස් වෙනස් කළ නොහැකි ය, සාමාන්‍යයෙන් ප්‍රාථමිකයන් විකෘති වේ. නූල් ද ප්‍රාථමික නොවේ, එය වස්තුවකි. එපමණක් නොව, නූල් වල යටින් පවතින ව්‍යුහය විකෘති අරාවකි. එහි ඇති වෙනස් කළ නොහැකි දෙය වන්නේ අරා වල ආවේනික ස්වභාවය වීමයි.
kingfrito_5005

3
මෙය තර්කයේ විශාල වශයෙන් අර්ථකථන ස්වභාවය පෙන්වා දෙන තවත් පිළිතුරකි. මෙම පිළිතුරෙහි දක්වා ඇති යොමු අර්ථ දැක්වීම ජාවා "පසු-යොමු කිරීම" බවට පත් කරයි. කතුවරයා අවසාන ඡේදයේ ඇති තරම්ම එය පිළිගන්නේ එය “ප්‍රායෝගිකව වෙන් කොට හඳුනාගත නොහැකි” බව පවසමිනි. OP ඉල්ලන්නේ ජාවා ක්‍රියාත්මක කිරීම තේරුම් ගැනීමට ඇති ආශාව නිසා නොව ජාවා නිවැරදිව භාවිතා කරන්නේ කෙසේද යන්න තේරුම් ගැනීම නිසා යැයි මම සැක කරමි. එය ප්‍රායෝගිකව වෙන් කොට හඳුනාගත නොහැකි නම්, සැලකිලිමත් වීමේ තේරුමක් නැති අතර ඒ ගැන සිතීම පවා කාලය නාස්තියක් වනු ඇත.
ලොඩුවිජ්

331

ජාවා අගය අනුව යොමු කරයි.

එබැවින් ඔබට ඇතුලත් වන යොමුව වෙනස් කළ නොහැක.


27
නමුත් නැවත නැවතත් පුනරාවර්තනය වන දෙය “තර්ක මගින් සම්මත කරන ලද වස්තූන්ගේ වටිනාකම ඔබට වෙනස් කළ නොහැක” යන්න පැහැදිලිවම අසත්‍යයකි. ඔබට ඒවා වෙනත් වස්තුවකට යොමු කිරීමට නොහැකි විය හැක, නමුත් ඒවායේ ක්‍රම ඇමතීමෙන් ඔබට ඒවායේ අන්තර්ගතය වෙනස් කළ හැකිය. IMO මෙයින් අදහස් කරන්නේ ඔබ යොමු කිරීම්වල සියලු ප්‍රතිලාභ නැති කර ගන්නා අතර අමතර ඇපකර ලබා නොගන්නා බවයි.
ටිම්ම්ම්

34
මම කවදාවත් කිව්වේ නැහැ "ඔබට තර්ක වලින් සම්මත කරන ලද වස්තූන්ගේ වටිනාකම වෙනස් කළ නොහැක". ජාවා භාෂාව පිළිබඳ සත්‍ය ප්‍රකාශයක් වන “ක්‍රම තර්කයක් ලෙස සම්මත කරන ලද වස්තු යොමු කිරීමේ වටිනාකම ඔබට වෙනස් කළ නොහැක” යනුවෙන් මම කියමි. නිසැකවම ඔබට වස්තුවේ තත්වය වෙනස් කළ හැකිය (එය වෙනස් නොවන තාක් කල්).
ScArcher2

20
ඔබට ඇත්ත වශයෙන්ම ජාවා තුළ වස්තූන් යැවිය නොහැකි බව මතක තබා ගන්න; වස්තූන් ගොඩවල් මත රැඳේ. වස්තූන් සඳහා දර්ශක සම්මත කළ හැකිය (ඒවා හැඳින්වෙන ක්‍රමය සඳහා තොග රාමුවට පිටපත් කරනු ලැබේ). එබැවින් ඔබ කිසි විටෙකත් සම්මත කළ අගය (දර්ශකය) වෙනස් නොකරයි, නමුත් ඔබට එය අනුගමනය කිරීමට සහ එය පෙන්වන ගොඩට ඇති දේ වෙනස් කිරීමට ඔබට නිදහස තිබේ. එය සම්මතයෙන් වටිනාකමක්.
ස්කොට් ස්ටැන්ච්ෆීල්ඩ්

10
ඔබ දැන් යොමු කිරීමක් කළා වගේද? ජාවා තවමත් පිටපත් කරන ලද යොමු-භාෂාවක් වන නිසා මම එය ජය ගන්නෙමි. එය පිටපත් කරන ලද සඳහනක් වීම පාරිභාෂිතය වෙනස් නොකරයි. යොමු කිරීම් දෙකම එකම වස්තුවකට යොමු කරයි. මෙය පාරිශුද්ධවාදියෙකුගේ තර්කයක් ...
ජෝන් ස්ට්‍රික්ලර්

3
ජාවා වස්තුවක් පසු නොකරයි, එය දර්ශකයේ අගය වස්තුව වෙත යොමු කරයි. මෙය නව විචල්‍යයක මුල් වස්තුවේ මතක ස්ථානයට නව දර්ශකයක් නිර්මාණය කරයි. ඔබ මෙම දර්ශක විචල්‍යයේ අගය (එය පෙන්වා දෙන මතක ලිපිනය) ක්‍රමයකින් වෙනස් කරන්නේ නම්, ක්‍රමවේදය අමතන්නාගේ මුල් දර්ශකය නවීකරණය නොකෙරේ. ඔබ පරාමිතිය යොමු කිරීමක් ලෙස හඳුන්වන්නේ නම්, එය මුල්
සඳහනේ

238

"Pass-by-reference vs pass-by-value" ගැන වාද කිරීම සුපිරි ප්‍රයෝජනවත් නොවන බව මට හැඟේ.

"ජාවා යනු කුමක් වුවත් (යොමු / අගය)" යැයි ඔබ කියන්නේ නම්, කෙසේ වෙතත්, ඔබ සම්පූර්ණ පිළිතුරක් සපයන්නේ නැත. මතකයේ සිදුවන්නේ කුමක්ද යන්න තේරුම් ගැනීමට බලාපොරොත්තු වන අමතර තොරතුරු කිහිපයක් මෙන්න.

අපි ජාවා ක්‍රියාවට නැංවීමට පෙර තොග / ගොඩවල් පිළිබඳ බිඳ වැටීමේ පා course මාලාව: ආපනශාලාවක තහඩු තොගයක් වැනි වටිනාකම් පිළිවෙලට හා පිළිවෙලට පිළිවෙලට තබයි. සංචයේ ඇති මතකය (ගතික මතකය ලෙසද හැඳින්වේ) අශෝභන හා අසංවිධිත වේ. ජේවීඑම් හට හැකි සෑම තැනකම අවකාශය සොයා ගන්නා අතර එය භාවිතා කරන විචල්‍යයන් තවදුරටත් අවශ්‍ය නොවන බැවින් එය නිදහස් කරයි.

හරි හරී. පළමුවෙන්ම, දේශීය ප්‍රාථමිකයන් සිරස් අතට යයි. එබැවින් මෙම කේතය:

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

මෙහි ප්‍රති results ල:

ප්‍රාථමිකයේ තොගයේ

ඔබ වස්තුවක් ප්‍රකාශ කර ක්ෂණිකව ක්‍රියාත්මක කරන විට. නියම වස්තුව ගොඩ ගසයි. තොගයේ කුමක් සිදුවේද? ගොඩේ ඇති වස්තුවේ ලිපිනය. C ++ ක්‍රමලේඛකයින් මෙය දර්ශකයක් ලෙස හැඳින්වුවද සමහර ජාවා සංවර්ධකයින් "දර්ශකය" යන වචනයට විරුද්ධ ය. කුමක් වුවත්. වස්තුවේ ලිපිනය තොගයේ පවතින බව දැන ගන්න.

එසේ වැනි:

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

ab * 7ch aint one!

අරාව යනු වස්තුවකි, එබැවින් එය ගොඩවල් මත ද ගමන් කරයි. අරාවෙහි ඇති වස්තූන් ගැන කුමක් කිව හැකිද? ඔවුනට තමන්ගේම ගොඩවල් අවකාශයක් ලැබෙන අතර, එක් එක් වස්තුවේ ලිපිනය අරාව තුළට යයි.

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

මාක්ස් සහෝදරයෝ

ඉතින්, ඔබ ක්‍රමයක් අමතන විට කුමක් සිදුවේද? ඔබ වස්තුවක් තුළ ගමන් කරන්නේ නම්, ඔබ සැබවින්ම ගමන් කරන්නේ වස්තුවේ ලිපිනයයි. සමහරු ලිපිනයේ “වටිනාකම” යැයි පැවසිය හැකි අතර සමහරු පවසන්නේ එය වස්තුවට යොමු කිරීමක් පමණක් බවයි. “යොමු” සහ “අගය” යෝජනා කරන්නන් අතර ශුද්ධ යුද්ධයේ ආරම්භය මෙයයි. ඔබ එය හඳුන්වන දෙය එතරම් වැදගත් නොවේ.

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);
}

එක් නූලක් සාදනු ලබන අතර ඒ සඳහා අවකාශය ගොඩවල් තුළ වෙන් කරනු ලැබේ. දෙවන නූලෙහි ලිපිනය hisNameපළමුවැන්නාට සමාන බැවින් නව නූල් සාදනු නොලැබේ. නව ගොඩවල් ඉඩක් වෙන් නොකෙරේ, නමුත් නව හඳුනාගැනීමක් තොගයේ නිර්මාණය වේ. එවිට අපි අමතන්නෙමු shout(): නව සිරස් රාමුවක් සාදනු ලබන අතර නව හඳුනාගැනීමක් nameසාදනු ලබන අතර දැනටමත් පවතින සංගීතයේ ලිපිනය පවරා ඇත.

ලා ඩා ඩී ඩා ඩා

ඉතින්, වටිනාකම, යොමු කිරීම? ඔබ "අර්තාපල්" කියනවා.


7
කෙසේ වෙතත්, ඔබ වඩාත් සංකීර්ණ උදාහරණයකින් පසු විපරමක් කළ යුතු අතර එහිදී ශ්‍රිතයක් විචල්‍යයක් වෙනස් කරන බව පෙනේ.
බ්‍රයන් පීටර්සන්

34
ජනතාව වන නිසා, ගොඩක් එදිරිව සිරස් එකතුවේ "සැබෑ ප්රශ්නය වටා නැටුම්" නොවේ නොවන සැබෑ ප්රශ්නය. එය ක්‍රියාවට නැංවීමේ විස්තරයක් වන අතර නරකම දෙය වැරදිය. (ගූගල් "පලා විශ්ලේෂණය" එවිට වස්තූන් විශාල සංඛ්යාවක් සිටින බවට සැලකෙතත් අඩංගු එය අඩුක්කුව සජීවී ද්රව්ය සඳහා ඉතා හැකි ය. නැහැ සැබෑ ප්රශ්නයක් අඩුක්කුව සජීවී.) හරියටම සඳහන් වර්ග සහ අගය වර්ග අතර වෙනස - විශේෂයෙන්, විමර්ශන ආකාරයේ විචල්‍යයක අගය යොමු කිරීමක් මිස එය යොමු කරන වස්තුව නොවේ.
cHao

8
එය "ක්‍රියාත්මක කිරීමේ විස්තරයක්" වන අතර එය කිසියම් වස්තුවක් මතකයේ රැඳී සිටින්නේ කොතැනදැයි පෙන්වීමට ජාවා කිසි විටෙකත් අවශ්‍ය නොවන අතර ඇත්ත වශයෙන්ම එම තොරතුරු කාන්දු වීම වළක්වා ගැනීමට අධිෂ් determined ාන කරගෙන සිටී. එමඟින් වස්තුව තොගයේ තැබිය හැකි අතර ඔබ කිසි විටෙකත් නොදැන සිටියි. ඔබ සැලකිලිමත් නම්, ඔබ අවධානය යොමු කරන්නේ වැරදි දෙයකට - සහ මේ අවස්ථාවේ දී, එයින් අදහස් කරන්නේ සැබෑ ප්‍රශ්නය නොසලකා හැරීමයි.
cHao

10
කෙසේ වෙතත්, "ප්‍රාථමිකයන් සිරස් අතට යයි" වැරදිය. ප්‍රාථමික දේශීය විචල්‍යයන් තොගයේ පවතී. (ඒවා ප්‍රශස්තිකරණය කර නොමැති නම්, ඇත්ත වශයෙන්ම.) එහෙත්, එසේ නම්, දේශීය යොමු විචල්‍යයන් කරන්න . වස්තුවක් තුළ අර්ථ දක්වා ඇති ප්‍රාථමික සාමාජිකයන් වස්තුව ජීවත්වන ඕනෑම තැනක ජීවත් වේ.
cHao

9
මෙහි අදහස් සමඟ එකඟ වන්න. ගොඩගැසීම / ගොඩවල් යනු අතුරු ප්‍රශ්නයක් වන අතර එය අදාළ නොවේ. සමහර විචල්යයන් තොගයේ තිබිය හැකිය, සමහර ඒවා ස්ථිතික මතකයේ (ස්ථිතික විචල්යයන්), සහ ගොඩවල් මත ගොඩක් ජීවත් වේ (සියලු වස්තු සාමාජික විචල්යයන්). මෙම විචල්‍යයන්ගෙන් කිසිවක් යොමු කිරීමෙන් සම්මත කළ නොහැක: කැඳවුම් ක්‍රමයකින් තර්කයක් ලෙස සම්මත වන විචල්‍යයක අගය වෙනස් කිරීමට කිසිසේත් නොහැකි ය. එබැවින් ජාවා හි කිසිදු පසු-යොමු කිරීමක් නොමැත.
fishinear

195

වෙනස පෙන්වීමට, පහත සඳහන් C ++ සහ ජාවා ස්නිපෙට් සංසන්දනය කරන්න :

C ++ හි: සටහන: නරක කේතය - මතක කාන්දු වීම! නමුත් එය කාරණය පෙන්නුම් කරයි.

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"
}

ජාවා හි,

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"
}

ජාවා සතුව ඇත්තේ සම්මත වර්ග දෙකකි: සාදන ලද වර්ග සඳහා අගය සහ වස්තු වර්ග සඳහා දර්ශකයේ අගය අනුව.


7
+1 මම Dog **objPtrPtrC ++ උදාහරණයට එකතු කරමි , එමඟින් අපට “යොමු කරන” දර්ශකය වෙනස් කළ හැකිය.
අම්රෝ

1
නමුත් ජාවා හි දී ඇති ප්‍රශ්නයට මෙය පිළිතුරු සපයන්නේ නැත. ඇත්ත වශයෙන්ම, ජාවා ක්‍රමයේ ඇති සෑම දෙයක්ම පාස් බයි අගය වේ, ඊට වඩා දෙයක් නැත.
tauitdnmd

2
මෙම උදාහරණයෙන් ඔප්පු වන්නේ ජාවා සී අංකයේ දර්ශකයට සමාන අගයක් භාවිතා කරන බවයි? C හි අගය පසු කිරීම මූලික වශයෙන් කියවිය හැක්කේ කොතැනින්ද? අවසානයේදී, මෙම සම්පූර්ණ
නූලම

179

ජාවා අගය අනුව වස්තු වෙත යොමු කරයි.


මෙය හොඳම පිළිතුරයි. කෙටි හා නිවැරදි.
woens

166

මූලික වශයෙන්, වස්තු පරාමිතීන් නැවත පැවරීම තර්කයට බලපාන්නේ නැත, උදා.

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

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

"Hah!"වෙනුවට මුද්‍රණය කරනු ඇත null. මෙය ක්‍රියාත්මක වීමට හේතුව barඑහි වටිනාකමෙහි පිටපතක් වන අතර bazඑය යොමු දැක්වීමක් පමණි "Hah!". එය සත්‍ය සඳහනක් නම්, fooනැවත අර්ථ bazදැක්වීමට ඉඩ තිබුණි null.


8
බාර්එක යනු මුලින් එකම වස්තුවකට යොමු කරන යොමු බාස් (හෝ බාස් අන්වර්ථය) හි පිටපතක් යැයි මම කියමි.
මැක්ස් සූම්

සංගීත පන්තිය සහ අනෙකුත් සියලුම පන්ති අතර සුළු වෙනසක් නැද්ද?
මෙහඩි කරමොස්ලි

152

බාබරා ලිස්කොව් ගැන කිසිවෙකු තවමත් සඳහන් කර නැති බව මට විශ්වාස කළ නොහැකිය. ඇය 1974 දී CLU නිර්මාණය කර ඇති විට, ඇය මෙම එකම පාරිභාෂික ශබ්ද ප්රශ්නය තුළට දිව ගියා, ඇය පදය නිර්මාණය බෙදා හදා විසින් ඇමතුමක් (ද ලෙස හඳුන්වන වස්තුව හුවමාරු විසින් ඇමතුමක් හා වස්තුව මගින් ඇමතුමක් වටිනාකම ඇමතුමක් වටිනාකම කොහෙද "මෙම සුවිශේෂ සිද්ධිය සඳහා) යොමු කිරීමක් ".


3
නාමකරණයෙහි මෙම වෙනසට මම කැමතියි. ජාවා වස්තු සඳහා බෙදාගැනීමෙන් ඇමතුමට සහය දැක්වීම අවාසනාවකි, නමුත් අගය අනුව ඇමතීම නොවේ (C ++ මෙන්). ජාවා අගය ඇමතුම් සඳහා සහය දක්වන්නේ ප්‍රාථමික දත්ත වර්ග සඳහා මිස සංයුක්ත දත්ත වර්ග සඳහා නොවේ.
ඩෙරෙක් මහර්

2
අපට අතිරේක යෙදුමක් අවශ්‍ය යැයි මම නොසිතමි - එය නිශ්චිත වර්ගයක වටිනාකමක් සඳහා අගය ඉක්මවා යාමකි. “ප්‍රාථමික ඇමතුම” එකතු කිරීමෙන් යම් පැහැදිලි කිරීමක් එකතු වේද?
ස්කොට් ස්ටැන්ච්ෆීල්ඩ්


සමහර ගෝලීය සන්දර්භ වස්තුවක් බෙදාගැනීමෙන් හෝ වෙනත් යොමු කිරීම් අඩංගු සන්දර්භ වස්තුවක් පසු කිරීමෙන් මට යොමු කළ හැකිද? මම තවමත් අගය ඉක්මවා යමි, නමුත් අවම වශයෙන් මට වෙනස් කිරීමට සහ ඒවා වෙනත් දෙයකට යොමු කිරීමට මට හැකි යොමු වෙත ප්‍රවේශය ඇත .
යෝයෝ

1
An සංජීව්: ඇමතුම-වස්තුව-බෙදාගැනීම යනු වටිනාකමින් සම්මත වීමේ විශේෂ අවස්ථාවකි. කෙසේ වෙතත්, බොහෝ අය දැඩි ලෙස තර්ක කරන්නේ ජාවා (සහ ඒ හා සමාන භාෂාවන් වන පයිතන්, රූබි, ඊසීඑම්එස්ක්‍රිප්ට්, ස්මාල්ටෝක්) සම්මතයෙන් යොමු වන බවයි. මම එය සම්මතයෙන් වටිනාකමක් ලෙස හැඳින්වීමට කැමැත්තෙමි, නමුත් වස්තුව-බෙදාගැනීම ඇමතීම සාධාරණ යෙදුමක් ලෙස පෙනේ, එය සම්මතයෙන් වටිනාකමක් නැතැයි තර්ක කරන අයට පවා එකඟ විය හැකිය.
ජෝර්ග් ඩබ් මිට්ටාග්

119

මේ කාරණය පිළිබඳ මුල පුරන ලද්දේ යන වචනය බවයි සඳහන් ප්රකාශනය තුළ මාර්ගයෙන් යන වචනය සුපුරුදු අර්ථය සම්පූර්ණයෙන්ම වෙනස් දෙයක් "ඇසුරින් සමත්" සඳහන් ජාවා.

සාමාන්‍යයෙන් ජාවා යොමුවෙහි අර්ථය වන්නේ වස්තුවකට aa යොමු කිරීමයි . නමුත් තාක්ෂණික යෙදුම් ක්‍රමලේඛන භාෂා න්‍යායෙන් යොමු / වටිනාකමෙන් සම්මත වන්නේ විචල්‍යය රඳවාගෙන සිටින මතක සෛලයට යොමු වීමක් ගැන වන අතර එය සම්පූර්ණයෙන්ම වෙනස් දෙයකි.


7
EGevorg - එහෙනම් “NullPointerException” යනු කුමක්ද?
හොට් ලික්ස්

5
Ot හොට්: ජාවා පැහැදිලි පාරිභාෂිතය මත පදිංචි වීමට පෙර සිට අවාසනාවකට නම් කරන ලද ව්‍යතිරේකයකි. C # හි අර්ථ නිරූපණයට සමාන ව්‍යතිරේකය NullReferenceException ලෙස හැඳින්වේ.
ජැක් බී

4
ජාවා පාරිභාෂිතය තුළ “යොමු” භාවිතා කිරීම අවබෝධයට බාධාවක් වන බව සෑම විටම මට පෙනේ.
හොට් ලික්ස්

මම මෙම ඊනියා "වස්තූන් වෙත යොමු කරන්නන්" ලෙස හැඳින්වීමට ඉගෙන ගත්තා. මෙය අපැහැදිලි බව අඩු කළේය.
moronkreacionz

86

ජාවා හි සෑම දෙයක්ම යොමු වේ, එබැවින් ඔබට එවැනි දෙයක් ඇති විට: Point pnt1 = new Point(0,0);ජාවා පහත සඳහන් දේ කරයි:

  1. නව ලක්ෂ්‍ය වස්තුවක් නිර්මාණය කරයි
  2. නව ලක්ෂ්‍ය යොමු කිරීමක් නිර්මාණය කරන අතර කලින් යොමු කරන ලද ලක්ෂ්‍ය වස්තුව මත ලක්ෂ්‍යය වෙත යොමු කිරීම (යොමු කරන්න) .
  3. මෙතැන් සිට, පොයින්ට් වස්තු ජීවිතය හරහා, ඔබට pnt1 යොමුව හරහා එම වස්තුවට ප්‍රවේශ විය හැකිය. එබැවින් ජාවාහිදී ඔබ වස්තුව එහි යොමු කිරීම මගින් හසුරුවන බව අපට පැවසිය හැකිය.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ජාවා ක්‍රමයෙන් තර්ක ඉදිරිපත් නොකරයි; එය ඒවා වටිනාකමින් පසු කරයි. මම මෙම වෙබ් අඩවියෙන් උදාහරණයක් භාවිතා කරමි :

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);  
}

වැඩසටහනේ ප්‍රවාහය:

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(" ");

අපේක්ෂිත ප්‍රතිදානය වනුයේ:

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

මෙම පේළියේ 'පාස්-බයි-අගය' නාට්‍යයට යයි ...

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

ආශ්රිත pnt1සහ pnt2ඇත වටිනාකම විසින් සම්මත කරන මාධ්යයක් දැන් ඔබේ යොමු කරන වෙනත් ඕනැම ක්රමය වෙත pnt1හා pnt2ඔවුන්ගේ ඇති copiesනම් arg1හා arg2.ඒ pnt1හා arg1 ලකුණු එකම වස්තුවකට. ( pnt2සහ සමාන වේ arg2) රූප විස්තරය මෙහි ඇතුළත් කරන්න

තුළ trickyක්රමය:

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

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඊළඟට trickyක්රමයේ

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

මෙන්න, ඔබ මුලින්ම නව tempලක්ෂ්‍ය යොමු කිරීමක් නිර්මාණය කරන අතර එය යොමු කිරීම වැනි එකම ස්ථානයකට arg1යොමු වේ. එවිට ඔබ සඳහන් ගමන් arg1කිරීමට ස්ථානය වැනි එම ස්ථානයට arg2යොමු. අවසාන වශයෙන් arg2ඇත පෙන්වා වැනි එම ස්ථානයට temp.

රූප විස්තරය මෙහි ඇතුළත් කරන්න

මෙහි සිට විෂය පථය trickyක්රමය ගොස් ඇති නම් හා ඔබ විසින් තවත් නිර්දේශන සඳහා ප්රවේශයන් නොමැත: arg1, arg2, temp. නමුත් වැදගත් සටහනක් නම්, මෙම යොමු කිරීම් 'ජීවිතයේ' සිටින විට ඔබ කරන සෑම දෙයක්ම ඔවුන් පෙන්වා දෙන වස්තුවට ස්ථිර ලෙස බලපානු ඇත.

එබැවින් ක්‍රමවේදය ක්‍රියාත්මක කිරීමෙන් පසු tricky, ඔබ නැවත පැමිණෙන විට ඔබට mainමෙම තත්වය තිබේ: රූප විස්තරය මෙහි ඇතුළත් කරන්න

දැන්, වැඩසටහන සම්පූර්ණයෙන්ම ක්‍රියාත්මක කිරීම වනුයේ:

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

7
ජාවා වලදී ඔබ "ජාවා තුළ සියල්ල යොමු වේ" යැයි පැවසූ විට ඔබ අදහස් කරන්නේ සියලු වස්තු යොමු කර ඇති බවයි. ප්‍රාථමික දත්ත වර්ග යොමු කිරීම මඟින් සම්මත නොවේ.
එරික්

හුවමාරු කළ අගය ප්‍රධාන ක්‍රමයෙන් මුද්‍රණය කිරීමට මට හැකියාව තිබේ. උපක්‍රම ක්‍රමයේදී, පහත දැක්වෙන ප්‍රකාශය එක් කරන්න, arg1.x = 1; arg1.y = 1; arg2.x = 2; arg2.y = 2;එබැවින් arg1 දැන් pnt2 refrence සහ arg2 hold pnt1 යොමුව ලෙස තබා ඇති බැවින් එහි මුද්‍රණයX1: 2 Y1: 2 X2: 1 Y2: 1
Shahid Ghafoor

85

ජාවා සැමවිටම වටිනාකමින් සම්මත වේ, යොමු මඟින් සම්මත නොවේ

පළමුවෙන්ම, අගය අනුව ගමන් කිරීම සහ යොමු කිරීම යනු කුමක්ද යන්න අප තේරුම් ගත යුතුය.

අගය පසුකර යන්නෙන් අදහස් වන්නේ ඔබ සම්මත පරාමිතියේ අගය මතකයේ පිටපතක් සාදන බවයි. මෙය සත්‍ය පරාමිතියේ අන්තර්ගතයේ පිටපතකි .

යොමු කිරීම හරහා ගමන් කිරීම (ලිපිනයෙන් පාස් ලෙසද හැඳින්වේ) යන්නෙන් අදහස් කරන්නේ සත්‍ය පරාමිතියේ ලිපිනයේ පිටපතක් ගබඩා කර ඇති බවයි.

සමහර විට ජාවා විසින් යොමු කිරීමෙන් පාස් පිළිබඳ මිත්‍යාව ලබා දිය හැකිය. පහත උදාහරණය භාවිතා කිරීමෙන් එය ක්‍රියාත්මක වන්නේ කෙසේදැයි බලමු:

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;
}

මෙම වැඩසටහනේ ප්‍රතිදානය:

changevalue

පියවරෙන් පියවර තේරුම් ගනිමු:

Test t = new Test();

අප කවුරුත් දන්නා පරිදි, එය ගොඩේ වස්තුවක් නිර්මාණය කර යොමු අගය නැවත t වෙත ලබා දෙනු ඇත. උදාහරණයක් ලෙස, t හි අගය යැයි සිතමු 0x100234(සත්‍ය JVM අභ්‍යන්තර අගය අපි නොදනිමු, මෙය උදාහරණයක් පමණි).

පළමු නිදර්ශනය

new PassByValue().changeValue(t);

T ශ්‍රිතය වෙත යොමු කිරීමේදී එය වස්තු පරීක්ෂණයේ සත්‍ය යොමු අගය කෙලින්ම සමත් නොවනු ඇත, නමුත් එය t හි පිටපතක් නිර්මාණය කර එය ශ්‍රිතයට ලබා දෙනු ඇත. එය අගය අනුව ගමන් කරන බැවින් , එය සත්‍යයේ සඳහනට වඩා විචල්‍යයේ පිටපතක් පසු කරයි. T හි අගය යැයි අප පැවසූ බැවින් 0x100234, t සහ f යන දෙකටම එකම අගයක් ඇති අතර එබැවින් ඒවා එකම වස්තුවකට යොමු වේ.

දෙවන නිදර්ශනය

F යොමුව භාවිතා කරමින් ඔබ ශ්‍රිතයේ කිසිවක් වෙනස් කළහොත් එය වස්තුවේ පවතින අන්තර්ගතයන් වෙනස් කරයි. changevalueශ්‍රිතය තුළ යාවත්කාලීන වන ප්‍රතිදානය අපට ලැබුණේ එබැවිනි .

මෙය වඩාත් පැහැදිලිව තේරුම් ගැනීමට පහත උදාහරණය සලකා බලන්න:

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;
}

මෙය විසි NullPointerExceptionකරයිද? නැත, මන්ද එය යොමු කරනුයේ යොමු පිටපතක් පමණි. යොමු දැක්වීමක් හරහා ගමන් කිරීමේදී NullPointerException, පහත දැක්වෙන පරිදි , එය විසි කළ හැකිය:

තෙවන නිදර්ශනය

මෙය උපකාරී වනු ඇතැයි අපේක්‍ෂා කරමු.


71

ඔබ භාවිතා කරන භාෂාව කුමක් වුවත්, යොමු කිරීමක් සැමවිටම වටිනාකමක් වේ.

කොටු දර්ශනයෙන් පිටත ලබා ගැනීම, අපි එකලස් කිරීම හෝ පහත් මට්ටමේ මතක කළමනාකරණය දෙස බලමු. CPU මට්ටමින් ඕනෑම දෙයක් පිළිබඳ සඳහනක් මතකයට හෝ CPU ලේඛනයකට ලියා ඇත්නම් එය වහාම වටිනාකමක් බවට පත්වේ . (ඒ නිසාම දර්ශකය හොඳ අර්ථ දැක්වීමක් වේ. එය වටිනාකමක් වන අතර ඒ සමඟම අරමුණක් ඇත).

මතකයේ දත්ත සතුව ස්ථානය හා එම ස්ථානයේ අගය (බයිට වලින්, වචනය, ඕනෑම දෙයක්) නැත. ප්රාන්ත සභාව තුළ අපි දෙන්න පහසු විසඳුමක් ඇති නම කිසියම් ස්ථානය (විචල්ය හෙවත්), නමුත් කේතය සම්පාදනය විට, assembler හුදෙක් විස්ථාපනය නම නම් කරන ස්ථානය සමග ඔබේ බ්රවුසරයේ IP ලිපින වසම් නම් විස්ථාපනය වගේ.

හරය දක්වා ඕනෑම භාෂාවකින් ඕනෑම භාෂාවක් යොමු නොකර එය යොමු කිරීම තාක්‍ෂණිකව කළ නොහැකි ය (එය වහාම වටිනාකමක් බවට පත් වූ විට).

අපට විචල්ය ෆූ එකක් ඇති බව කියමු, එහි පිහිටීම මතකයේ 47 වන බයිට් වල වන අතර එහි අගය 5 වේ. අපට තවත් විචල්යයක් වන රෙෆ් 2 ෆූ 223 වන බයිට් මතකයේ ඇති අතර එහි වටිනාකම 47 ක් වනු ඇත. මෙම Ref2Foo තාක්ෂණික විචල්යයක් විය හැකිය , වැඩසටහන විසින් පැහැදිලිවම නිර්මාණය කර නැත. ඔබ වෙනත් තොරතුරක් නොමැතිව 5 සහ 47 දෙස බැලුවහොත් ඔබට පෙනෙන්නේ සාරධර්ම දෙකක් පමණි . ඔබ ඒවා යොමු ලෙස භාවිතා කරන්නේ නම් 5අප වෙත යා යුතුය:

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

පැනීමේ වගු ක්‍රියා කරන්නේ එලෙසයි.

අපට Foo හි අගය සමඟ ක්‍රමයක් / ශ්‍රිතයක් / ක්‍රියාපටිපාටියක් කැඳවීමට අවශ්‍ය නම්, භාෂාව සහ එහි ක්‍රමවේදය ආයාචනා ක්‍රම කිහිපයක් මත පදනම්ව විචල්‍යය ක්‍රමයට යැවිය හැකි ක්‍රම කිහිපයක් තිබේ:

  1. 5 CPU ලේඛනයකට පිටපත් වේ (එනම් EAX).
  2. 5 තොගයට PUSHd ලබා ගනී.
  3. 47 CPU ලේඛනයකට පිටපත් වේ
  4. 47 තොගයට තල්ලු කරන්න.
  5. 223 CPU ලේඛනයකට පිටපත් වේ.
  6. 223 ට PUSHd තොගයට ලැබේ.

වටිනාකමට ඉහළින් ඇති සෑම අවස්ථාවකම - පවත්නා අගයක පිටපතක් - නිර්මාණය කර ඇති අතර, එය හැසිරවීමේ ක්‍රමය දක්වා දැන් පවතී. ඔබ ක්‍රමවේදය තුළ "ෆූ" ලියන විට, එය එක්කෝ ඊඒඑක්ස් වෙතින් කියවනු ලැබේ, නැතහොත් ස්වයංක්‍රීයව අවලංගු කරන ලද හෝ ද්විත්ව විරූපණය කළ විට, ක්‍රියාවලිය රඳා පවතින්නේ භාෂාව ක්‍රියාත්මක වන ආකාරය සහ / හෝ ෆූ වර්ගය නියම කරන දේ මත ය. අවලංගු කිරීමේ ක්‍රියාවලිය මගහරින තුරු මෙය සංවර්ධකයාගෙන් සැඟවී ඇත. එබැවින් යොමු කිරීමක් නිරූපණය කිරීමේදී අගය වේ , මන්ද යොමු කිරීම යනු ක්‍රියාවට නැංවිය යුතු අගයකි (භාෂා මට්ටමින්).

දැන් අපි ක්‍රමයට Foo සමත් වී ඇත:

  • 1. සහ 2. නඩුවේදී ඔබ Foo ( Foo = 9) වෙනස් කළහොත් එය දේශීය විෂය පථයට බලපාන්නේ ඔබ සතුව වටිනාකමේ පිටපතක් ඇති බැවිනි. ක්‍රමයේ ඇතුළත සිට මුල් ෆූ පිහිටා තිබුණේ කොතැනදැයි අපට තීරණය කළ නොහැක.
  • 3. සහ 4 වැනි අවස්ථාවලදී ඔබ පෙරනිමි භාෂා ව්‍යුහයන් භාවිතා කර Foo ( Foo = 11) වෙනස් කරන්නේ නම් , එය ගෝලීය වශයෙන් Foo වෙනස් කළ හැකිය (භාෂාව මත රඳා පවතී, එනම් ජාවා හෝ පැස්කල්ගේ procedure findMin(x, y, z: integer;var m වැනි: integer); ). කෙසේ වෙතත්, විරූපණ ක්‍රියාවලිය මග හැරීමට භාෂාව ඔබට ඉඩ දෙන්නේ නම්, ඔබට වෙනස් කළ හැකිය 47, කියන්න 49. එම අවස්ථාවේදී ෆූ ඔබ එය කියවා ඇත්නම් එය වෙනස් කර ඇති බව පෙනේ, මන්ද ඔබ එයට දේශීය දර්ශකය වෙනස් කර ඇති බැවිනි . ඔබ ක්‍රමවේදය තුළ මෙම ෆූ වෙනස් කළහොත් ( Foo = 12) ඔබ බොහෝ විට වැඩසටහන ක්‍රියාත්මක කිරීම (අ. වැඩසටහන සහ එයට ලිවීම මඟින් ධාවන කේතය වෙනස් කරනු ඇත (Foo දැන් නොමැත 47). නමුත් Foo හි වටිනාකම47ගෝලීය වශයෙන් වෙනස් නොවූයේ, ක්‍රමවේදය තුළ ඇති එකක් පමණි, මන්ද 47එම ක්‍රමයට පිටපතක් ද විය.
  • 5. සහ 6 වැනි අවස්ථාවන්හිදී ඔබ 223ක්‍රමවේදය තුළ වෙනස් කරන්නේ නම් එය 3 හෝ 4 හි ඇති සමාන ව්‍යසනය නිර්මාණය කරයි. (දර්ශකයක්, දැන් නරක අගයක් පෙන්වා, එය නැවත දර්ශකයක් ලෙස භාවිතා කරයි) නමුත් මෙය තවමත් දේශීය ය 223 පිටපත් කළ පරිදි ගැටළුව . කෙසේ වෙතත්, ඔබට අවලංගු කිරීමට Ref2Foo(එනම් 223), යොමු කළ අගය වෙත ළඟා වීමට සහ වෙනස් කිරීමට හැකි නම් 47, කියන්න 49, එය ගෝලීය වශයෙන් ෆූට බලපානු ඇත , මන්ද මෙම අවස්ථාවේ දී ක්‍රමවේදයන්හි පිටපතක් 223 ලැබුණද, යොමු කිරීම 47පවතින්නේ එක් වරක් පමණක් වන අතර එය වෙනස් කිරීම කිරීමට 49සෑම හේතු වනු ඇත Ref2Fooවැරදි අගය කිරීමට ද්විත්ව dereferencing.

වැදගත් නොවන තොරතුරු මත නිශ්ශබ්ද කිරීම, සම්මතයෙන් යොමු කරන භාෂා පවා ශ්‍රිතයන්ට අගයන් ලබා දෙනු ඇත, නමුත් එම ශ්‍රිතයන් දන්නවා ඒවා අවලංගු කිරීමේ අරමුණු සඳහා භාවිතා කළ යුතු බව. මෙම සම්මත-යොමු-අගය-ක්‍රමලේඛකයාගෙන් සැඟවී ඇත්තේ එය ප්‍රායෝගිකව නිෂ් less ල වන නිසා සහ පාරිභාෂිතය සම්මතයෙන් -යොමු කිරීම පමණි .

දැඩි පසු-අගය ද නිෂ් less ල ය, එයින් අදහස් වන්නේ අප අරාව සමඟ ක්‍රමයක් ලෙස තර්කයක් ලෙස හඳුන්වන සෑම අවස්ථාවකම 100 Mbyte අරාවක් පිටපත් කළ යුතු බවයි, එබැවින් ජාවා අගය ඉක්මවා සම්මත කළ නොහැක. සෑම භාෂාවක්ම මෙම දැවැන්ත අරාව (වටිනාකමක් ලෙස) වෙත යොමු කරනු ඇති අතර, එම අරාව ක්‍රමවේදය තුළ දේශීයව වෙනස් කළ හැකි නම් හෝ ගෝලීයව අරාව වෙනස් කිරීමට (ජාවා මෙන්) ක්‍රමයට ඉඩ දෙන්නේ නම් පිටපත්-ලිවීමේ යාන්ත්‍රණයක් භාවිතා කරයි. අමතන්නාගේ දැක්ම) සහ භාෂා කිහිපයක් මඟින් යොමු අගය වෙනස් කිරීමට ඉඩ දෙයි.

ඒ නිසා කෙටි හා ජාවා ම පාරිභාෂිතය තුළ දී, ජාවා යනු සමත්-විසින්-අගය එහිදී අගය , එක්කෝ: විය හැකි සැබෑ වටිනාකම හෝ අගය වූ නිරූපණය වන බව සඳහන් .


1
පාස්-බයි-යොමු සහිත භාෂාවක, සම්මත කළ දෙය (යොමු කිරීම) ආධ්‍යාත්මික ය; ලබන්නා එය පිටපත් කිරීමට "නොසිතයි". ජාවා හි, අරාව සම්මත කිරීම යනු “වස්තු හඳුනාගැනීමක්” - 24601 වන වස්තුව අරා එකක් වූ විට “වස්තුව # 24601” යැයි කියන කඩදාසි පෙත්තකට සමාන වේ. ලබන්නාට අවශ්‍ය ඕනෑම තැනක "වස්තුව # 24601" පිටපත් කළ හැකි අතර, "වස්තුව # 24601" යැයි පවසන කඩදාසි පෙත්තක් ඇති ඕනෑම කෙනෙකුට ඕනෑම අරාව මූලද්‍රව්‍යයක් සමඟ අවශ්‍ය ඕනෑම දෙයක් කළ හැකිය. සම්මත කරන ලද බිටු වල රටාව ඇත්ත වශයෙන්ම "වස්තුව # 24601" යැයි නොකියනු ඇත, නමුත් ...
සුපර් කැට්

... වැදගත්ම කරුණ නම්, අරාව හදුනා ගන්නා වස්තු-හැඳුනුම්පත ලබන්නාට එම වස්තු හැඳුනුම්පත අවශ්‍ය ඕනෑම තැනක ගබඩා කර එය අවශ්‍ය ඕනෑම කෙනෙකුට ලබා දිය හැකි අතර ඕනෑම ලබන්නෙකුට අරාව වෙත පිවිසීමට හෝ වෙනස් කිරීමට හැකි වේ. අවශ්‍යයි. ඊට හාත්පසින්ම වෙනස්ව, පැස්කල් වැනි භාෂාවකින් අරාව සම්මත කර ඇත්නම්, කැඳවුම් ක්‍රමයට අරාව සමඟ අවශ්‍ය ඕනෑම දෙයක් කළ හැකි නමුත්, අරාව වෙනස් කිරීමට කේතයට ඉඩ සැලසෙන පරිදි එම සඳහන ගබඩා කිරීමට නොහැකි විය. එය නැවත පැමිණි පසු.
සුපර් කැට්

ඇත්ත වශයෙන්ම, පැස්කල්හිදී ඔබට සෑම විචල්‍යයකම ලිපිනය ලබා ගත හැකිය , addrඑය සම්මතයෙන් හෝ දේශීයව පිටපත් කළද, එය ටයිප් නොකළද, @එය වර්ගය සමඟ කළත්, ඔබට පසුව යොමු කළ විචල්‍යය වෙනස් කළ හැකිය (දේශීයව පිටපත් කළ ඒවා හැර). නමුත් ඔබ එය කරන්නේ මන්දැයි මට තේරෙන්නේ නැත. ඔබේ උදාහරණයේ ඇති කඩදාසි ස්ලිප් (වස්තුව # 24601) යොමු කිරීමකි, එහි අරමුණ වන්නේ මතකයේ ඇති අරාව සොයා ගැනීමට උපකාර කිරීමයි, එහි කිසිදු අරා දත්තයක් අඩංගු නොවේ. ඔබ ඔබේ වැඩසටහන නැවත අරඹන්නේ නම්, එකම අරාවෙහි වෙනත් වස්තු-හැඳුනුම්පතක් ලැබෙනු ඇත, එහි අන්තර්ගතය පෙර ධාවනයේදී මෙන් සමාන වුවද.
karatedog

මම සිතුවේ "@" ක්‍රියාකරු සම්මත පැස්කල්හි කොටසක් නොවන නමුත් එය පොදු දිගුවක් ලෙස ක්‍රියාත්මක කරන බවයි. එය සම්මතයේ කොටසක්ද? මගේ අදහස වූයේ සත්‍ය පාස්-බයි-රීෆ් සහිත භාෂාවක, සහ කාලානුරූපී නොවන දර්ශකයක් ආධ්‍යාත්මික වස්තුවකට තැනීමේ හැකියාවක් නොමැති, අරාව පසුකර යාමට පෙර, විශ්වයේ ඕනෑම තැනක, අරාවකට එකම සඳහනක් ඇති කේතය. යොමුකරුට "වංචා" නොකළහොත් එය පසුව එකම සඳහනක් ඇති බව දැන ගත හැකිය. ජාවා හි එය ඉටු කර ගත හැකි එකම ආරක්ෂිත ක්‍රමය වනුයේ තාවකාලික වස්තුවක්
තැනීමයි

... එය සංකේතවත් කරන AtomicReferenceඅතර යොමු හෝ එහි ඉලක්කය නිරාවරණය නොකරයි, නමුත් ඒ වෙනුවට ඉලක්කයට දේවල් කිරීමේ ක්‍රම ඇතුළත් වේ; වස්තුව සම්මත කළ කේතය ආපසු පැමිණි පසු, AtomicReference[එහි නිර්මාතෘ සෘජු සඳහනක් තබා ඇති] අවලංගු කර අතහැර දැමිය යුතුය. එමඟින් නිසි අර්ථකථන ලබා දෙනු ඇත, නමුත් එය මන්දගාමී හා අශෝභන වනු ඇත.
සුපර් කැට්

70

ජාවා යනු අගය අනුව ඇමතුමකි

එය ක්‍රියාත්මක වන ආකාරය

  • ඔබ සැමවිටම යොමු වටිනාකමෙහි බිටු පිටපතක් ලබා දෙයි!

  • එය ප්‍රාථමික දත්ත වර්ගයක් නම්, මෙම බිටු වල ප්‍රාථමික දත්ත වර්ගයේම අගය අඩංගු වේ, ඒ නිසා අපි ක්‍රමවේදය තුළ ශීර්ෂයේ අගය වෙනස් කළහොත් එය පිටතින් සිදුවන වෙනස්කම් පිළිබිඹු නොකරයි.

  • ඒ වගේ වස්තුවක් දත්ත වර්ගය වේ නම් ෆූ foo = නව ෆූ () එසේ නම් මේ අවස්ථාවේ දී වස්තුව ලිපිනය පිටපතක් ගොනුව කෙටිමං වැනි වෙයි, අපි පෙළ ගොනුවක් හිතන්න abc.txt දී \ ඩෙස්ක්ටොප්: සී සහ අප කෙටිමං කරන්න සිතමු එකම ගොනුව සහ මෙය C: \ ඩෙස්ක්ටොප් \ abc-shortcut තුළ තබන්න, එබැවින් ඔබ C: \ ඩෙස්ක්ටොප් \ abc.txt වෙතින් ගොනුව වෙත පිවිසෙන විට සහ ලියන්න, 'ස්ටැක් ' ගොනුව වසා දමා නැවත ගොනුව විවෘත කළ විට ඔබ ලිවීම 'යනු ක්‍රමලේඛකයින්ට ඉගෙන ගත හැකි විශාලතම මාර්ගගත ප්‍රජාවයි' එවිට සම්පූර්ණ ගොනු වෙනස් කිරීම වනුයේ 'ක්‍රමලේඛකයන්ට ඉගෙනීමට ඇති විශාලතම මාර්ගගත ප්‍රජාව වන්නේ ස්ටැක් පිටාර ගැලීමයි'එහි අර්ථය වන්නේ ඔබ ගොනුව විවෘත කරන ස්ථානයෙන්, අප එකම ගොනුවකට ප්‍රවේශ වන සෑම අවස්ථාවකම, මෙහිදී අපට ෆූ ගොනුවක් ලෙස උපකල්පනය කළ හැකි අතර 123hd7h හි ගබඩා කර ඇති foo යැයි සිතමු (මුල් ලිපිනය C: \ ඩෙස්ක්ටොප් \ abc.txt වැනි ) ලිපිනය සහ 234jdid ( C: \ ඩෙස්ක්ටොප් \ abc-shortcut වැනි පිටපත් කළ ලිපිනය එහි ඇත්ත වශයෙන්ම ගොනුවේ මුල් ලිපිනය අඩංගු වේ) .. එබැවින් වඩා හොඳ අවබෝධයක් සඳහා කෙටිමං ගොනුවක් සාදා දැනෙන්න ..


66

මෙය ආවරණය කරන විශිෂ්ට පිළිතුරු දැනටමත් තිබේ. බෙදාහදා ගැනීමෙන් කුඩා දායකත්වයක් ලබා දීමට මට අවශ්‍ය වියC ++ හි Pass-by-reference සහ Java හි Pass-by-value අතර හැසිරීම් අතර වෙනස ඉතා සරල උදාහරණයක් (සම්පාදනය කරනු ඇත) .

කරුණු කිහිපයක්:

  1. “යොමුව” යන පදය වෙනම අර්ථ දෙකක් සහිත අධික බරකි. ජාවාහි එය හුදෙක් දර්ශකයක් අදහස් කරයි, නමුත් "පාස්-බයි-යොමු" සන්දර්භය තුළ එයින් අදහස් වන්නේ සම්මත වූ විචල්‍යයට හසුරුවීමයි.
  2. ජාවා යනු පාස්-බයි-අගයයි . ජාවා යනු සී (වෙනත් භාෂා අතර) පැවත එන්නෙකි. C ට පෙර, FORTRAN සහ COBOL වැනි පෙර භාෂා කිහිපයක් PBR සඳහා සහය දැක්වූ නමුත් C එසේ නොකළේය. පීබීආර් මෙම අනෙකුත් භාෂාවන්ට උප චර්යාවන් තුළ සම්මත විචල්‍යයන් වෙනස් කිරීමට ඉඩ ලබා දුන්නේය. එකම දේ ඉටු කිරීම සඳහා (එනම් ශ්‍රිත තුළ විචල්‍යයන්ගේ අගයන් වෙනස් කිරීම), සී ක්‍රමලේඛකයෝ විචල්‍යයන් වෙත විචල්‍යයන් වෙත යොමු කළහ. ජාවා වැනි සී විසින් දේවානුභාවයෙන් ලියන ලද භාෂා මෙම අදහස ණයට ගත් අතර සී මෙන් ක්‍රමවේදයන් වෙත යොමු කිරීම දිගටම කරගෙන යයි. නැවතත්, මෙය "යොමු කිරීම" යන වචනයට වඩා "යොමු කිරීම" යන වචනයේ වෙනස් භාවිතයකි.
  3. "&" අක්‍ෂරය භාවිතා කරමින් යොමු පරාමිතියක් ප්‍රකාශ කිරීමෙන් සී ++ මඟින් පාස්-බයි-යොමු කිරීමට ඉඩ දෙයි (එය සී සහ සී ++ යන දෙකෙහිම "විචල්‍යයක ලිපිනය" දැක්වීමට භාවිතා කරන එකම අක්‍ෂරයම වේ). උදාහරණයක් ලෙස, අපි යොමු කිරීමකින් දර්ශකයකින් ගමන් කරන්නේ නම්, පරාමිතිය සහ තර්කය එකම වස්තුවකට යොමු නොවේ. ඒ වෙනුවට ඒවා එකම විචල්‍යයයි. යමෙකු වෙනත් ලිපිනයකට හෝ ශුන්‍යයට සකසා ඇත්නම්, අනෙකා ද එසේ කරයි.
  4. පහත දැක්වෙන C ++ උදාහරණයේ දී මම යොමු කිරීමක් මඟින් ශුන්‍ය අහෝසි කරන ලද නූලකට යොමු කරමි . පහත දැක්වෙන ජාවා උදාහරණයේ දී මම ජාවා යොමු කිරීමක් නූලකට යොමු කරමි (නැවතත්, නූලකට දර්ශකයක් ලෙස). අදහස් දැක්වීමේ ප්‍රතිදානය සැලකිල්ලට ගන්න.

යොමු උදාහරණයෙන් C ++ සමත් වීම:

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>
}

අගය උදාහරණයකින් ජාවා සමත් "ජාවා යොමු කිරීමක්"

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().
     }
}

සංස්කරණය කරන්න

කිහිප දෙනෙක් අදහස් ලියා ඇති අතර එයින් පෙන්නුම් කරන්නේ ඔවුන් මගේ උදාහරණ දෙස නොබලන බවයි. එසේ නැතහොත් ඔවුන්ට c ++ උදාහරණය නොලැබෙන බවයි. විසන්ධි වන්නේ කොහේදැයි විශ්වාස නැත, නමුත් c ++ උදාහරණය අනුමාන කිරීම පැහැදිලි නැත. මම එකම උදාහරණය පැස්කල්හි පළ කරමි, මන්ද යත්, පාස්-බයි-යොමු කිරීම පැස්කල්හි වඩා පිරිසිදු යැයි සිතන නමුත් මම වැරදියි. මම මිනිසුන්ව තව තවත් ව්‍යාකූල කරනවා විය හැකිය; මම බලාපොරොත්තු නොවෙමි.

පැස්කල් වලදී, යොමු කරන ලද පරාමිතීන් "var පරාමිතීන්" ලෙස හැඳින්වේ. පහත දැක්වෙන setToNil ක්‍රියාපටිපාටියේ, කරුණාකර 'ptr' පරාමිතියට පෙර 'var' යන පදය සටහන් කරන්න. අවධානය යොමුකළ මෙම ක්රියාවලිය සඳහා ගමන් කරන විට, එය සම්මත කර ගනු ඇත සඳහනක් විසින් . හැසිරීම සැලකිල්ලට ගන්න: මෙම ක්‍රියා පටිපාටිය ptr nil ලෙස සකසන විට (එය NULL සඳහා පැස්කල් කතා), එය තර්කය නිල් ලෙස සකසනු ඇත - ඔබට එය ජාවා හි කළ නොහැක.

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.

සංස්කරණය 2

කෙන් ආර්නෝල්ඩ්, ජේම්ස් ගොස්ලිං (ජාවා නිර්මාණය කළ පුද්ගලයා) සහ ඩේවිඩ් හෝම්ස්, 2 වන පරිච්ඡේදයේ, 2.6.5 කොටසෙහි "ජාවා ක්‍රමලේඛන භාෂාව" වෙතින් උපුටා ගත් කොටස්

ක්‍රම සඳහා වන සියලුම පරාමිතීන් "අගය අනුව" සම්මත වේ. වෙනත් වචන වලින් කිවහොත්, ක්‍රමයක පරාමිති විචල්‍යයන්ගේ අගයන් තර්ක ලෙස දක්වා ඇති ඉන්වොකර්ගේ පිටපත් වේ.

ඔහු වස්තූන් සම්බන්ධයෙන් එකම කරුණක් ඉදිරිපත් කරයි. . .

ඔබ පරාමිතිය වස්තුවක් යොමු වන විට, එය, වස්තුව යොමු-නොවන වස්තුව බව ම-බව කරුණාවෙන් යුතු "වටිනාකම" සම්මත .

එම කොටසේම අවසානය දක්වා ඔහු ජාවා ගැන පුළුල් ප්‍රකාශයක් කරන්නේ වටිනාකමින් පමණක් වන අතර කිසි විටෙකත් එය යොමු නොකරයි.

ජාවා ක්‍රමලේඛන භාෂාව යොමු කිරීමෙන් වස්තු පසු නොකරයි; එය අගය අනුව වස්තු යොමු කරයි . එකම යොමුවෙහි පිටපත් දෙකක් එකම සත්‍ය වස්තුවකට යොමු වන හෙයින්, එක් යොමු විචල්‍යයක් හරහා සිදු කරන ලද වෙනස්කම් අනෙකා හරහා දැකිය හැකිය. හරියටම එක් පරාමිතියක් පසුකරන මාදිලියක් ඇත- අගය අනුව ගමන් කරන්න - සහ දේවල් සරල ලෙස තබා ගැනීමට උපකාරී වේ.

පොතේ මෙම කොටසේ ජාවාහි පරාමිති සම්මත කිරීම සහ පාස්-බයි-රීෆරන්ස් සහ පාස්-බයි-අගය අතර වෙනස පිළිබඳව විශාල පැහැදිලි කිරීමක් ඇති අතර එය ජාවාහි නිර්මාතෘ විසිනි. ඕනෑම කෙනෙකුට එය කියවීමට මම උනන්දු කරවන්නෙමි, විශේෂයෙන් ඔබට තවමත් ඒත්තු ගැන්වී නොමැති නම්.

මා සිතන්නේ මාදිලි දෙක අතර වෙනස ඉතා සියුම් වන අතර ඔබ සැබවින්ම පාස්-බයි-යොමු කිරීම භාවිතා කළ වැඩසටහන්කරණය කර නොමැති නම්, මාදිලි දෙකක් වෙනස් වන තැන මග හැරීම පහසුය.

මෙය විවාදය සමථයකට පත් කරනු ඇතැයි මම බලාපොරොත්තු වෙමි, නමුත් බොහෝ විට එසේ නොවනු ඇත.

සංස්කරණය 3

මම මේ පෝස්ට් එක ගැන ටිකක් උමතු විය හැකිය. ජාවා නිෂ්පාදකයින් නොදැනුවත්වම වැරදි තොරතුරු පතුරුවා හරින බව මට හැඟෙන නිසා විය හැකිය. දර්ශකයන් සඳහා “යොමු” යන වචනය භාවිතා කරනවා වෙනුවට ඔවුන් වෙනත් දෙයක් භාවිතා කර තිබේ නම්, ඩිංගල්බෙරි කියන්න, කිසිදු ගැටළුවක් ඇති නොවනු ඇත. ඔබට කිව හැකිය, "ජාවා ඩිංගල්බෙරි පසු කරන්නේ වටිනාකමින් මිස යොමු කිරීමකින් නොවේ", කිසිවෙකු ව්‍යාකූල නොවනු ඇත.

ජාවා සංවර්ධකයින්ට පමණක් මේ සම්බන්ධයෙන් ගැටළුවක් ඇත්තේ එයයි. ඔවුන් "යොමු කිරීම" යන වචනය දෙස බලා එහි තේරුම හරියටම දන්නා බව සිතයි, එබැවින් ඔවුන් විරුද්ධ තර්කය සලකා බැලීමට පවා කරදර වන්නේ නැත.

කෙසේ වෙතත්, මම පැරණි පෝස්ට් එකක අදහස් දැක්වීමක් දුටුවෙමි, එය බැලූන් ප්‍රතිසමයක් සෑදූ අතර එය මා සැබවින්ම කැමති විය. කෙතරම්ද යත්, කාරණය නිදර්ශනය කිරීම සඳහා කාටූන් කට්ටලයක් සෑදීම සඳහා ක්ලිප්-ආර්ට් කිහිපයක් මැලියම් කිරීමට මම තීරණය කළෙමි.

අගය අනුව යොමු කිරීමක් සම්මත කිරීම - යොමු කිරීම වෙනස් කිරීම අමතන්නාගේ විෂය පථය තුළ පිළිබිඹු නොවේ, නමුත් වස්තුවෙහි වෙනස්කම් වේ. මෙයට හේතුව යොමු කිරීම පිටපත් කර ඇති නමුත් මුල් පිටපත සහ පිටපත යන දෙකම එකම වස්තුවකට යොමු වීමයි. අගය අනුව වස්තු යොමු කිරීම

යොමු කිරීම හරහා ගමන් කරන්න - යොමු පිටපතක් නොමැත. තනි යොමු කිරීම අමතන්නා සහ කැඳවනු ලබන ශ්‍රිතය යන දෙකම බෙදා ගනී. යොමුකිරීමේ හෝ වස්තුවේ දත්තවල යම් වෙනසක් ඇමතුම්කරුගේ විෂය පථය තුළ පිළිබිඹු වේ. යොමුව අනුව සමත් වන්න

සංස්කරණය 4

මෙම මාතෘකාව පිළිබඳ ලිපි මම දැක ඇත්තෙමි, එය ජාවා හි පරාමිති සම්මත කිරීම අවම මට්ටමක ක්‍රියාත්මක කිරීම විස්තර කරයි, එය වියුක්ත අදහසක් සංයුක්ත කරන බැවින් එය විශිෂ්ට සහ ඉතා ප්‍රයෝජනවත් යැයි මම සිතමි. කෙසේ වෙතත්, මට ප්‍රශ්නය වන්නේ භාෂාවේ පිරිවිතරයේ විස්තර කර ඇති හැසිරීම පිළිබඳ හැසිරීම හැසිරීමේ තාක්‍ෂණික ක්‍රියාත්මක කිරීම ගැන ය. මෙය ජාවා භාෂා පිරිවිතර, 8.4.1 වගන්තියේ උපුටා ගැනීමකි :

ක්‍රමවේදය හෝ ඉදිකිරීම්කරු ආයාචනා කළ විට (§15.12), සත්‍ය තර්ක ප්‍රකාශනයේ අගයන් ක්‍රමයේ හෝ ඉදිකිරීම්කරුගේ ශරීරය ක්‍රියාත්මක කිරීමට පෙර අලුතින් සාදන ලද පරාමිති විචල්‍යයන්, ප්‍රකාශිත එක් එක් වර්ගය ආරම්භ කරයි. විධිමත් පරාමිතිය වෙත යොමු කිරීම සඳහා DeclaratorId හි ඇති හැඳුනුම්පත ක්‍රමයේ හෝ ඉදිකිරීම්කරුගේ ශරීරයේ සරල නමක් ලෙස භාවිතා කළ හැකිය.

එහි තේරුම, ක්‍රමයක් ක්‍රියාත්මක කිරීමට පෙර ජාවා විසින් සම්මත කරන ලද පරාමිතීන්ගේ පිටපතක් නිර්මාණය කිරීමයි. විද්යාලයේ අවස්තා අධ්යයනය කළ බොහෝ මිනිසුන් මෙන්, මම භාවිතා "එන්ටර් ද ඩ්රැගන් 'පොත" වන THE අවස්තා පොත. 1 වන පරිච්ඡේදයේ "ඇමතුම් අනුව අගය" සහ "ඇමතුම අනුව-යොමු කිරීම" පිළිබඳ හොඳ විස්තරයක් එහි ඇත. ඇමතුම් අනුව අගය විස්තරය ජාවා පිරිවිතර සමඟ හරියටම ගැලපේ.

90 දශකයේ දී මම සම්පාදකයින් හැදෑරූ විට, මම 1986 සිට පොතේ පළමු සංස්කරණය භාවිතා කළ අතර එය ජාවාට අවුරුදු 9 ක් හෝ 10 ක් පමණ කලින් නියම කර ඇත. කෙසේ වෙතත්, මම 2007 සිට 2 වන සංස්කරණයේ පිටපතක් හරහා දිව ගියෙමි , එහි ඇත්ත වශයෙන්ම ජාවා ගැන සඳහන් වේ! 1.6.6 වගන්තියේ “පරාමිති පසු කිරීමේ යාන්ත්‍රණයන්” යනුවෙන් ලේබල් කර ඇති පරාමිතිය ඉතා හොඳින් ගමන් කිරීම විස්තර කරයි. ජාවා ගැන සඳහන් වන "කෝල්-බයි-අගය" යන මාතෘකාව යටතේ උපුටා ගැනීමක් මෙන්න:

ඇමතුම අනුව, සත්‍ය පරාමිතිය ඇගයීමට ලක් කෙරේ (එය ප්‍රකාශනයක් නම්) හෝ පිටපත් කිරීම (එය විචල්‍යයක් නම්). අගය කැඳවනු ලබන ක්‍රියාපටිපාටියේ අනුරූප විධිමත් පරාමිතියට අයත් ස්ථානයේ තබා ඇත. මෙම ක්‍රමය සී සහ ජාවා වල භාවිතා වන අතර එය සී ++ හි මෙන්ම වෙනත් බොහෝ භාෂාවලද පොදු විකල්පයකි.


4
අවංකවම, ඔබට මෙම පිළිතුර සරල කළ හැක්කේ ජාවා අගය අනුව සම්මත වර්ග සඳහා පමණි. වස්තුවෙන් උරුම වන සෑම දෙයක්ම reference ලදායි ලෙස යොමු කිරීම මඟින් සිදු කරනු ලැබේ, එහිදී යොමු කිරීම ඔබ පසු කරන දර්ශකය වේ.
ස්කූබා ස්ටීව්

1
U ජුවාන් මෙන්ඩිස්, මම උදාහරණයක් ලෙස C ++ භාවිතා කළෙමි; මට ඔබට වෙනත් භාෂාවලින් උදාහරණ ලබා දිය හැකිය. C ++ පැවතීමට බොහෝ කලකට පෙර “Pass by reference” යන පදය පැවතුනි. එය ඉතා නිශ්චිත අර්ථ දැක්වීමක් සහිත පෙළපොත් යෙදුමකි. අර්ථ දැක්වීම අනුව, ජාවා යොමු කිරීම මඟින් සම්මත නොවේ. ඔබට අවශ්‍ය නම් මෙම පදය දිගටම භාවිතා කළ හැකිය, නමුත් ඔබේ භාවිතය පෙළ පොත් අර්ථ දැක්වීමට අනුකූල නොවේ. එය හුදෙක් දර්ශකයකට යොමු කරන්නෙකු නොවේ. එය "යොමු කිරීම හරහා ගමන් කිරීමට" ඉඩ දීම සඳහා භාෂාව විසින් සපයන ලද ඉදිකිරීමකි. කරුණාකර මගේ උදාහරණය දෙස හොඳින් බලන්න, නමුත් කරුණාකර ඒ සඳහා මගේ වචනය ගෙන එය ඔබම සොයා බලන්න එපා.
සංජීව්

2
UtAutomatedMike මම සිතන්නේ ජාවා "පාස්-බයි-රීෆරන්ස්" ලෙස විස්තර කිරීම ද නොමඟ යවන සුළුය, ඒවායේ යොමු කිරීම දර්ශකයන්ට වඩා වැඩි දෙයක් නොවේ. සංජීව් අගය ලියා ඇති පරිදි, යොමු කිරීම සහ දර්ශකය යනු ජාවා නිර්මාණකරුවන් භාවිතා කරන දේ නොසලකා ඒවායේම අර්ථයක් ඇති පෙළ පොත් පද වේ.
Jrdrzej Dudkiewicz

1
ආර්ටානිස්සෙරාතුල් කාරණය සියුම් නමුත් සංකීර්ණ නොවේ. කරුණාකර මා පළ කළ කාටූනය දෙස බලන්න. එය අනුගමනය කිරීම ඉතා සරල බව මට හැඟුණි. ජාවා පාස්-බයි-අගය බව මතයක් පමණක් නොවේ. පාස්-බයි-අගය පිළිබඳ පෙළපොත් අර්ථ දැක්වීම අනුව එය සත්‍යයකි. එසේම, "සෑම විටම එය වටිනාකමින් සමත් යැයි පවසන පුද්ගලයින්ට" ජාවාහි නිර්මාතෘ ජේම්ස් ගොස්ලිං වැනි පරිගණක විද්‍යා scientists යින් ඇතුළත් වේ. කරුණාකර මගේ පොතේ "සංස්කරණය 2" යටතේ ඔහුගේ පොතේ උපුටා දැක්වීම් බලන්න.
සංජීව්

1
ජාවා (සහ JS වැනි වෙනත් භාෂා) තුළ "යොමු කිරීම හරහා යොමු කිරීම" මොනතරම් හොඳ පිළිතුරක්ද?
ෆෝල්ඩරය

56

මා දන්නා තරමින් ජාවා දන්නේ ඇමතුම අගය අනුව පමණි. මෙයින් අදහස් කරන්නේ ඔබ පිටපතක් සමඟ වැඩ කරන ප්‍රාථමික දත්ත වර්ග සඳහා වන අතර වස්තු සඳහා ඔබ යොමු වස්තුවක් සමඟ වැඩ කරනු ඇත. කෙසේ වෙතත් මම හිතන්නේ යම් යම් අන්තරායන් ඇත; උදාහරණයක් ලෙස, මෙය ක්‍රියා නොකරනු ඇත:

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);
}

මෙය ලෝක ආයුබෝවන් නොව හෙලෝ වර්ල්ඩ් ජනගහනය වනු ඇත. මන්දයත් හුවමාරු කිරීමේ ක්‍රියාවලියේදී ඔබ පිටපත් භාවිතා කරන අතර එය ප්‍රධාන වශයෙන් යොමු කිරීම් කෙරෙහි කිසිදු බලපෑමක් ඇති නොකරයි. නමුත් ඔබේ වස්තූන් වෙනස් කළ නොහැකි නම් ඔබට එය උදාහරණයක් ලෙස වෙනස් කළ හැකිය:

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);
}

මෙය විධාන රේඛාවේ හෙලෝ වර්ල්ඩ් ජනගහනය කරයි. ඔබ StringBuffer එක String බවට වෙනස් කළහොත් එය ආයුබෝවන් නිපදවන්නේ String වෙනස් කළ නොහැකි බැවිනි. උදාහරණයක් වශයෙන්:

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);
}

කෙසේ වෙතත් ඔබට මේ ආකාරයට නූල් සඳහා එතීම කළ හැකි අතර එමඟින් එය නූල් සමඟ භාවිතා කිරීමට හැකි වේ:

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);
}

සංස්කරණය කරන්න: නූල් දෙකක් "එකතු කිරීම" සඳහා StringBuffer භාවිතා කිරීමට මෙයද හේතුවක් බව මම විශ්වාස කරමි, මන්ද ඔබට String වැනි වෙනස් කළ නොහැකි වස්තූන් සමඟ කළ නොහැකි මුල් වස්තුව වෙනස් කළ හැකිය.


හුවමාරු පරීක්ෂණය සඳහා +1 - බොහෝ විට යොමු කිරීම සහ අගය අනුව යොමු කිරීමක් අතර වෙනස හඳුනා ගැනීමට ඇති සරලම හා සාපේක්ෂ ක්‍රමයයි . ඔබට පහසුවෙන් උත්සවයකට ලියන්න පුළුවන් යන සැකය swap(a, b)(1) හුවමාරු බව aහා bස්ථිතික ටයිප් ඉඩ (තවත් වර්ගය සමග එය භාවිතා අර්ථය කිසිවක් ප්රකාශ කර වර්ග වෙනස් වඩා අවශ්ය වන තාක් දුරට වර්ගය-අඥේයවාදියෙක් වේ අමතන්නා ගේ ඥානය, (2) සිට aසහ b) , සහ (3) අමතන්නාට පොයින්ටරයක් ​​හෝ නමක් පැහැදිලිව සම්මත කිරීම අවශ්‍ය නොවේ, එවිට භාෂාව යොමු කිරීම සඳහා සහාය වේ.
cHao

".. ප්‍රාථමික දත්ත වර්ග සඳහා ඔබ පිටපතක් සමඟ වැඩ කරනු ඇති අතර වස්තූන් සඳහා ඔබ යොමු වස්තුවක් සමඟ වැඩ කරනු ඇත" - පරිපූර්ණ ලෙස ලියා ඇත!
රාවුල්

55

නැත, එය යොමු කිරීමකින් සමත් නොවේ.

ජාවා භාෂා පිරිවිතරයට අනුව ජාවා අගය අනුව ගමන් කරයි:

ක්‍රමවේදය හෝ ඉදිකිරීම්කරු ආයාචනා කරන විට (§15.12), සත්‍ය තර්ක ප්‍රකාශනවල අගයන් ක්‍රමයේ හෝ ඉදිකිරීම්කරුගේ ශරීරය ක්‍රියාත්මක කිරීමට පෙර අලුතින් සාදන ලද පරාමිති විචල්‍යයන් , ප්‍රකාශිත එක් එක් වර්ගය ආරම්භ කරයි. විධිමත් පරාමිතිය වෙත යොමු කිරීම සඳහා DeclaratorId හි ඇති හැඳුනුම්පත ක්‍රමයේ හෝ ඉදිකිරීම්කරුගේ ශරීරයේ සරල නමක් ලෙස භාවිතා කළ හැකිය .


52

උදාහරණ හතරක උපකාරයෙන් මගේ අවබෝධය පැහැදිලි කිරීමට උත්සාහ කරමි. ජාවා යනු අගය අනුව-අගය මිස යොමු කිරීම නොවේ

/ **

අගය අනුව සමත් වන්න

ජාවා හි, සියලු පරාමිතීන් අගය අනුව සම්මත වේ, එනම් ක්‍රම තර්කයක් පැවරීම අමතන්නාට නොපෙනේ.

* /

උදාහරණ 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";
    }
}

ප්‍රති ult ලය

output : output
value : Nikhil
valueflag : false

උදාහරණ 2:

/ ** * * අගය අනුව ගමන් කරන්න * * /

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";
    }
}

ප්‍රති ult ලය

output : output
value : Nikhil
valueflag : false

උදාහරණ 3:

/ ** මෙම 'අගය පසු කිරීම' 'යොමු කිරීම හරහා ගමන් කිරීම' පිළිබඳ හැඟීමක් ඇත

සමහර අය පවසන්නේ ප්‍රාථමික වර්ග සහ 'නූල්' යනු 'අගය අනුව ගමන් කිරීම' සහ වස්තූන් 'යොමු කිරීම හරහා ගමන් කිරීම' යන්නයි.

නමුත් මෙම උදාහරණයෙන් අපට තේරුම් ගත හැක්කේ එය වටිනාකමින් පමණක් නොවන බවයි, මෙහි දී අප යොමු කිරීම අගය ලෙස සම්මත කරන බව මතක තබා ගන්න. එනම්: යොමු කිරීම අගය අනුව සම්මත වේ. වෙනස් කළ හැකි වන්නේ එබැවිනි. එහෙත් එය දේශීය විෂය පථයෙන් පසුව සත්‍ය වේ. නමුත් අපට මුල් විෂය පථයෙන් පිටත සත්‍ය සඳහන වෙනස් කළ නොහැක. PassByValueObjectCase2 හි ඊළඟ උදාහරණයෙන් එහි තේරුම පෙන්නුම් කෙරේ.

* /

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";
    }
}

ප්‍රති ult ලය

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

උදාහරණ 4:

/ **

නිදර්ශන 3 (PassByValueObjectCase1.java) හි සඳහන් කර ඇති දේට අමතරව, මුල් විෂය පථයෙන් පිටත සත්‍ය සඳහන වෙනස් කළ නොහැක.

සටහන: මම කේතය අලවන්නේ නැත private class Student. සඳහා පන්ති අර්ථ දැක්වීම Studentඋදාහරණ 3 ට සමාන වේ.

* /

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";
    }

}

ප්‍රති ult ලය

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

49

ඔබට කිසි විටෙකත් ජාවා හි යොමු කිරීමකින් සමත් විය නොහැකි අතර, ක්‍රමවත් ඇමතුමකින් එකකට වඩා වැඩි අගයක් ආපසු ලබා දීමට ඔබට අවශ්‍ය වූ විට පැහැදිලිව පෙනෙන එක් ක්‍රමයක් වේ. C ++ හි පහත දැක්වෙන බිට් කේතය සලකා බලන්න:

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

සමහර විට ඔබට ජාවාහි එකම රටාව භාවිතා කිරීමට අවශ්‍ය නමුත් ඔබට එය කළ නොහැක; අවම වශයෙන් කෙලින්ම නොවේ. ඒ වෙනුවට ඔබට මේ වගේ දෙයක් කළ හැකිය:

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]);
}

පෙර පිළිතුරු වල පැහැදිලි කර ඇති පරිදි, ජාවා හි ඔබ අගයක් ලෙස අරාව වෙත දර්ශකයක් යොමු කරයි getValues. එය ප්‍රමාණවත් වන්නේ, ක්‍රමවේදය පසුව අරාව මූලද්‍රව්‍යය වෙනස් කරන අතර, සම්මුතියෙන් ඔබ බලාපොරොත්තු වන්නේ 0 වන මූලද්‍රව්‍යය ප්‍රතිලාභ අගය අඩංගු වනු ඇති බවයි. නිසැකවම ඔබට මෙය අවශ්‍ය නොවන පරිදි ඔබේ කේතය සැකසීම හෝ ප්‍රතිලාභ අගය අඩංගු පන්තියක් තැනීම හෝ එය සැකසීමට ඉඩ දීම වැනි වෙනත් ආකාරවලින් කළ හැකිය. නමුත් ඉහත C ++ හි ඔබට ලබා ගත හැකි සරල රටාව ජාවා හි නොමැත.


48

පිරිවිතරයන්ගෙන් වැඩි විස්තර එක් කිරීමට මෙම පිළිතුරට දායක වනු ඇතැයි මම සිතුවෙමි.

පළමුව, යොමු කිරීම හා අගය අනුව ගමන් කිරීම අතර වෙනස කුමක්ද?

යොමු කිරීම හරහා ගමන් කිරීම යන්නෙන් අදහස් කරන්නේ, හැඳින්වෙන ශ්‍රිතයන්ගේ පරාමිතිය, ඇමතුම්කරුවන්ගේ සම්මත තර්කයට සමාන වේ (අගය නොව, අනන්‍යතාවය - විචල්‍යය).

අගය අනුව ගමන් කිරීම යන්නෙන් අදහස් කරන්නේ, හැඳින්වෙන ශ්‍රිතයන්ගේ පරාමිතිය ඇමතුම්කරුවන්ගේ සම්මත තර්කයේ පිටපතක් වනු ඇත.

හෝ විකිපීඩියාවෙන්, පාස්-බයි-යොමු විෂය පිළිබඳ

ඇමතුමකින්-විමර්ශන ඇගයීමේ දී (පාස්-බයි-යොමු ලෙසද හැඳින්වේ), ශ්‍රිතයකට එහි වටිනාකමෙහි පිටපතක් නොව, තර්කයක් ලෙස භාවිතා කරන විචල්‍යයක් සඳහා ව්‍යංග යොමු කිරීමක් ලැබේ. මෙයින් සාමාන්‍යයෙන් අදහස් කරන්නේ ශ්‍රිතය තර්කය ලෙස භාවිතා කරන විචල්‍යය වෙනස් කිරීමට (එනම් පැවරීමට) හැකි බවයි - එය එහි ඇමතුම්කරුට පෙනෙනු ඇත.

හා විෂය මගහැරීම-විසින්-අගය

ඇමතුම් අනුව අගය තුළ, තර්ක ප්‍රකාශනය ඇගයීමට ලක් කරනු ලබන අතර, එහි ප්‍රති value ලයක් ලෙස ලැබෙන අගය ශ්‍රිතයේ අනුරූප විචල්‍යයට බැඳී ඇත [...]. ශ්‍රිතයට හෝ ක්‍රියා පටිපාටියට එහි පරාමිතීන්ට අගයන් පැවරිය හැකි නම්, එහි දේශීය පිටපත පමණක් පවරනු ලැබේ [...].

දෙවනුව, ජාවා එහි ක්‍රමවේදය සඳහා භාවිතා කරන්නේ කුමක්ද යන්න අප දැනගත යුතුය. මෙම ජාවා භාෂාව පිරිවිතර රාජ්යයන්

ක්‍රමවේදය හෝ ඉදිකිරීම්කරු ආයාචනා කළ විට (§15.12), සත්‍ය තර්ක ප්‍රකාශනයේ අගයන් ක්‍රමයේ හෝ ඉදිකිරීම්කරුගේ ශරීරය ක්‍රියාත්මක කිරීමට පෙර අලුතින් සාදන ලද පරාමිති විචල්‍යයන් , ප්‍රකාශිත එක් එක් වර්ගය ආරම්භ කරයි.

එබැවින් එය පරාමිතියේ විචල්‍යයට තර්කයේ අගය පවරයි (හෝ බන්ධනය කරයි).

තර්කයේ වටිනාකම කුමක්ද?

විමර්ශන වර්ග සලකා බලමු, ජාවා අතථ්‍ය යන්ත්‍ර පිරිවිතරයේ සඳහන් වේ

විමර්ශන වර්ග තුනක් ඇත : පන්ති වර්ග, අරා වර්ග සහ අතුරුමුහුණත් වර්ග. ඒවායේ අගයන් පිළිවෙලින් ගතිකව සාදන ලද පන්ති අවස්ථා, අරා, හෝ පන්ති අවස්ථා හෝ අතුරුමුහුණත් ක්‍රියාත්මක කරන අරා වෙත යොමු වේ.

මෙම ජාවා භාෂාව පිරිවිතර ද රාජ්යයන්ට

විමර්ශන අගයන් (බොහෝ විට හුදෙක් යොමු කිරීම්) මෙම වස්තූන් වෙත යොමුකරන්නන් වන අතර විශේෂ ශුන්‍ය යොමු කිරීමක් වන අතර එය කිසිදු වස්තුවක් ගැන සඳහන් නොවේ.

තර්කයක වටිනාකම (කිසියම් යොමු වර්ගයක) වස්තුවකට යොමු කිරීමකි. විචල්යයක්, විමර්ශන වර්ගයක් ආපසු ලබා දෙන වර්ගයක් සහිත ක්රමයක් ආයාචනා කිරීම සහ නිදර්ශන නිර්මාණ ප්රකාශනය ( new ...) සියල්ලම විමර්ශන වර්ගයේ අගයකට විසඳන බව සලකන්න .

ඒ නිසා

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

සියල්ලම යොමුකිරීමේ වටිනාකම Stringක්‍රමයට අලුතින් සාදන ලද පරාමිතියට සම්බන්ධ paramකරයි. පාස්-බයි-අගය අර්ථ දැක්වීම හරියටම මෙයයි. එනිසා ජාවා යනු අගය අනුව ය .

ක්‍රමවේදයක් ඉල්ලා සිටීමට හෝ යොමු කරන ලද වස්තුවක ක්ෂේත්‍රයකට ප්‍රවේශ වීමට ඔබට යොමු කිරීම අනුගමනය කළ හැකිය යන කාරණය සංවාදයට සම්පූර්ණයෙන්ම අදාල නොවේ. පාස්-බයි-යොමු කිරීමේ අර්ථ දැක්වීම විය

මෙයින් සාමාන්‍යයෙන් අදහස් කරන්නේ ශ්‍රිතය තර්කය ලෙස භාවිතා කරන විචල්‍යය වෙනස් කිරීමට (එනම් පැවරීමට) හැකි බවයි - එය එහි ඇමතුම්කරුට පෙනෙනු ඇත.

ජාවා හි, විචල්‍යය වෙනස් කිරීම යනු එය නැවත පැවරීමයි. ජාවා හි, ඔබ ක්‍රමවේදය තුළ විචල්‍යය නැවත පවරා ඇත්නම්, එය අමතන්නාගේ අවධානයට ලක් නොවනු ඇත. විචල්‍යය විසින් යොමු කරන ලද වස්තුව වෙනස් කිරීම සම්පූර්ණයෙන්ම වෙනස් සංකල්පයකි.


ප්රාථමික වටිනාකම් ද ජාවා Virtual Machine පිරිවිතර, අර්ථ ඇත මෙතන . වර්ගයෙහි අගය අනුරූපී අනුකලනය හෝ පාවෙන ලක්ෂ්‍ය අගය වේ, සුදුසු පරිදි කේතනය කර ඇත (8, 16, 32, 64, ආදිය බිටු).


42

ජාවා හි යොමු කිරීම් පමණක් සම්මත කර ඇති අතර ඒවා අගය අනුව සම්මත වේ:

ජාවා තර්ක සියල්ලම අගය අනුව සම්මත වේ (යොමුව ක්‍රමය භාවිතා කරන විට පිටපත් කරනු ලැබේ):

ප්‍රාථමික වර්ග සම්බන්ධයෙන් ගත් කල, ජාවා හැසිරීම සරල ය: අගය ප්‍රාථමික වර්ගයේ තවත් අවස්ථාවක පිටපත් කරනු ලැබේ.

වස්තු සම්බන්ධයෙන් ගත් කල, මෙය සමාන ය: වස්තු විචල්‍යයන් යනු “නව” මූල පදය භාවිතයෙන් නිර්මාණය කරන ලද වස්තු ලිපිනය පමණක් තබා ඇති දර්ශක (බාල්දි) වන අතර ඒවා ප්‍රාථමික වර්ග මෙන් පිටපත් කරනු ලැබේ.

හැසිරීම ප්‍රාථමික වර්ගවලට වඩා වෙනස් ලෙස පෙනිය හැකිය: පිටපත් කළ වස්තු විචල්‍යයේ එකම ලිපිනය (එකම වස්තුවට) අඩංගු වන බැවිනි. වස්තුවෙහි අන්තර්ගතය / සාමාජිකයන් තවමත් ක්‍රමවේදයක් තුළ වෙනස් කළ හැකි අතර පසුව පිටතින් ප්‍රවේශ විය හැකිය.

"නූල්" වස්තූන් නාගරික පුරාවෘත්තයට හොඳ ප්‍රති-නිදසුනක් ලෙස පෙනේ, "වස්තු යොමු කරනු ලබන්නේ යොමු කිරීමෙනි":

ඇත්ත වශයෙන්ම, ක්‍රමයක් භාවිතා කිරීමෙන්, ඔබට කිසි විටෙකත්, තර්කයක් ලෙස සම්මත කරන ලද නූලක වටිනාකම යාවත්කාලීන කිරීමට නොහැකි වනු ඇත:

නූල් වස්තුවක්, වෙනස් කළ නොහැකි අවසන් ප්‍රකාශිත අරා මඟින් අක්ෂර රඳවා තබා ගනී . "නව" භාවිතයෙන් වෙනත් අයෙකු විසින් ආදේශ කළ හැක්කේ වස්තුවේ ලිපිනය පමණි. විචල්‍යය යාවත්කාලීන කිරීම සඳහා "නව" භාවිතා කිරීමෙන්, විචල්‍යය මුලින් අගය අනුව සම්මත කර පිටපත් කළ බැවින් පිටතින් වස්තුවට ප්‍රවේශ වීමට ඉඩ නොදේ.


ඉතින් එය වස්තූන් සම්බන්ධයෙන් රීෆ් සහ ප්‍රාථමිකයන් සම්බන්ධයෙන් බයි වෝල් ද?
මොක්ස්

@mox කරුණාකර කියවන්න: වස්තූන් යොමු කිරීමෙන් සම්මත නොවේ, මෙය ලෙජන්ඩ් එකකි: String a = new string ("නොවෙනස්ව");
user1767316

1
A ආරොන් “යොමු කිරීම හරහා ගමන් කිරීම” යන්නෙන් අදහස් කරන්නේ “ජාවා හි“ යොමු කිරීමක් ”ලෙස හැඳින්වෙන වර්ගයක සාමාජිකයෙකු වන අගයක් පසුකර යන්න යන්න නොවේ. “යොමුව” යන භාවිතයන් දෙකෙන් අදහස් වන්නේ වෙනස් දේවල්ය.
ෆිලිප්සි

2
තරමක් අවුල් සහගත පිළිතුර. ඔබට ක්‍රමයකින් නූල් වස්තුවක් වෙනස් කිරීමට නොහැකි වීමට හේතුව, එය යොමු කිරීම මඟින් සම්මත කර ඇති අතර, නූල් වස්තූන් නිර්මාණයෙන් වෙනස් නොවන අතර ඔබට එවැනි දේ කළ නොහැක strParam.setChar ( i, newValue ). එයින් කියැවෙන්නේ, නූල්, වෙනත් ඕනෑම දෙයක් මෙන් අගය මගින් සම්මත වන අතර, නූල් යනු ප්‍රාථමික නොවන වර්ගයක් බැවින්, එම අගය අළුත් දේ සමඟ සාදන ලද දෙයට යොමු කිරීමක් වන අතර, ඔබට මෙය String.intern () භාවිතා කර පරීක්ෂා කළ හැකිය. .
zakmck

1
ඒ වෙනුවට, ඔබට param = "වෙනත් නූලක්" (නව නූලකට ("තවත් නූලකට") සමාන) හරහා නූලක් වෙනස් කළ නොහැක. සිරුර. නමුත් වෙනත් ඕනෑම වස්තුවකට එය සත්‍යයකි, වෙනස නම්, පන්ති අතුරුමුහුණත එයට ඉඩ දෙන විට, ඔබට param.changeMe () කළ හැකි අතර, පරාම් යොමු ලක්ෂ්‍යය තිබියදීත්, පරාම් එය යොමු කරන නිසා ඉහළ මට්ටමේ වස්තුව යොමු වේ. (ආමන්ත්‍රණය කළ ස්ථානය, සී පදයට අනුව) ක්‍රමයෙන් නැවත උත්පතනය කළ නොහැක.
zakmck

39

වෙනස, හෝ සමහර විට මට මතක ඇති ආකාරයට මුල් පෝස්ටරයේ සමාන හැඟීමකට යටත් විය: ජාවා සෑම විටම අගය අනුව ගමන් කරයි. ජාවා හි ඇති සියලුම වස්තූන් (ජාවාහි, ප්‍රාථමිකයන් හැර වෙනත් කිසිවක්) යොමු වේ. මෙම යොමු කිරීම් අගය අනුව සම්මත වේ.


2
ඔබගේ දෙවන සිට අවසාන වාක්‍යය නොමඟ යවන සුළු බව මට පෙනේ. "ජාවා හි ඇති සියලුම වස්තු යොමු කිරීම්" බව සත්‍ය නොවේ. එය යොමු කිරීම් වන එම වස්තූන් සඳහා යොමු කිරීම් පමණි.
ඩාවුඩ් ඉබ්න් කරීම්

37

බොහෝ අය එය කලින් සඳහන් කළ පරිදි, ජාවා සැමවිටම වටිනාකමින් යුක්ත වේ

වෙනස තේරුම් ගැනීමට ඔබට උපකාරී වන තවත් උදාහරණයක් මෙන්න ( සම්භාව්‍ය හුවමාරු උදාහරණය ):

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;
  }
}

මුද්‍රණ:

පෙර: a = 2, b = 3
පසු: a = 2, b = 3

මෙය සිදු වන්නේ iA සහ iB යනු සම්මත කරන ලද යොමු කිරීම්වල සමාන අගයක් ඇති නව දේශීය යොමු විචල්‍යයන් වන බැවිනි (ඒවා පිළිවෙලින් a සහ b වෙත යොමු වේ). එබැවින්, iA හෝ iB හි යොමු කිරීම් වෙනස් කිරීමට උත්සාහ කිරීම වෙනස් වන්නේ දේශීය විෂය පථයට මිස මෙම ක්‍රමයට පිටින් නොවේ.


32

ජාවා සතුව ඇත්තේ අගය අනුව පමණි. මෙය වලංගු කිරීම සඳහා ඉතා සරල උදාහරණයක්.

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();
}

4
ජාවා අගය අනුව ගමන් කරන බව දැකීමට ඇති පැහැදිලි, සරලම ක්‍රමය මෙයයි. obj( null) හි අගය initයොමු කරනු ලැබුවේ යොමු කිරීමක් සඳහා නොවේ obj.
ඩේවිඩ් ෂ්වාට්ස්

31

මම සෑම විටම එය "පිටපත පසුකර යන්න" ලෙස සිතමි. එය ප්‍රාථමික හෝ යොමු කිරීමක් වුවද වටිනාකමේ පිටපතකි. එය ප්‍රාථමික නම් එය අගය වන බිටු වල පිටපතක් වන අතර එය වස්තුවක් නම් එය යොමු කිරීමේ පිටපතකි.

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;
    }
}

ජාවාහි ප්‍රතිදානය PassByCopy:

name = Maxx
name = Fido

ප්‍රාථමික එතීමේ පන්ති සහ නූල් වෙනස් කළ නොහැකි බැවින් එම වර්ග භාවිතා කරන ඕනෑම උදාහරණයක් වෙනත් වර්ග / වස්තු මෙන් ක්‍රියා නොකරනු ඇත.


5
"පිටපත හරහා ගමන් කිරීම" යනු අගය පසුකර යාමේ තේරුමයි .
ටී. ජේ. ක්‍රෝඩර්

@TJCrowder. "පිටපත හරහා ගමන් කිරීම" ජාවා අරමුණු සඳහා එකම සංකල්පය ප්‍රකාශ කිරීමට වඩාත් සුදුසු ක්‍රමයක් විය හැකිය: මන්දයත් අර්ථ නිරූපණය මඟින් එය යොමු කිරීම හරහා යෑමට සමාන අදහසක් තුළ ෂූහෝර්න් කිරීම ඉතා අපහසු වන අතර එය ඔබට ජාවාහි අවශ්‍ය වේ.
මයික් මීයන්

ikemikerodent - කණගාටුයි, මම එය අනුගමනය කළේ නැහැ. :-) මෙම සංකල්ප සඳහා නිවැරදි කලා පද “පාස්-බයි-අගය” සහ “පාස්-බයි-යොමු” වේ. අළුත් ඒවා සෑදීමට වඩා අපි ඒවා භාවිතා කළ යුතුය (මිනිසුන්ට අවශ්‍ය විට ඔවුන්ගේ අර්ථ දැක්වීම් සැපයීම). මා ඉහත කීවේ "පිටපත හරහා ගමන් කිරීම" යනු "සම්මතයෙන් අගය" යන්නෙහි තේරුමයි, නමුත් ඇත්ත වශයෙන්ම, "පිටපත හරහා ගමන් කිරීම" යන්නෙන් අදහස් කරන්නේ කුමක්ද යන්න පැහැදිලි නැත - කුමක් පිටපතක් ද? වටිනාකම? (උදා: වස්තු යොමු කිරීම.) වස්තුවම? එබැවින් මම කලාවේ නියමයන්ට ඇලී සිටිමි. :-)
TJ Crowder

29

වෙනත් සමහර භාෂාවන් මෙන් නොව, ජාවා මඟින් ඔබට අගය-අගය සහ පාස්-බයි-යොමු අතර තෝරා ගැනීමට ඉඩ නොදේ - සියලු තර්ක සම්මතයෙන් සම්මත වේ. ක්‍රම ඇමතුමකට ක්‍රම දෙකකට අගයන් දෙකක් යැවිය හැකිය pri ප්‍රාථමික අගයන්හි පිටපත් (උදා: int සහ double වල අගයන්) සහ වස්තු පිළිබඳ යොමු පිටපත්.

ක්‍රමයක් ප්‍රාථමික ආකාරයේ පරාමිතියක් වෙනස් කරන විට, පරාමිතියෙහි වෙනස්වීම් ඇමතුම් ක්‍රමයේ මුල් තර්ක අගයට කිසිදු බලපෑමක් ඇති නොකරයි.

වස්තූන් සම්බන්ධයෙන් ගත් විට, වස්තූන්ම ක්‍රම වෙත යොමු කළ නොහැක. එබැවින් අපි වස්තුවෙහි යොමු (ලිපිනය) පසු කරමු. මෙම යොමුව භාවිතයෙන් අපට මුල් වස්තුව හැසිරවිය හැකිය.

ජාවා වස්තු නිර්මාණය කරන්නේ හා ගබඩා කරන්නේ කෙසේද: අපි වස්තුවක් නිර්මාණය කරන විට අපි වස්තු ලිපිනය යොමු විචල්‍යයක ගබඩා කරමු. පහත ප්‍රකාශය විශ්ලේෂණය කරමු.

Account account1 = new Account();

“ගිණුම් ගිණුම් 1” යනු යොමු විචල්‍යයේ වර්ගය සහ නමයි, “=” යනු පැවරුම් ක්‍රියාකරු, “නව” පද්ධතියෙන් අවශ්‍ය ඉඩ ප්‍රමාණය ඉල්ලා සිටී. නව පදයේ දකුණු පස ඇති ඉදිකිරීම්කරු වස්තුව නිර්මාණය කරන නව වචන පදය මගින් ව්‍යංගයෙන් හැඳින්වේ. පැවරුම් ක්‍රියාකරු භාවිතා කරමින් නිර්මාණය කරන ලද වස්තුවෙහි ලිපිනය (නිවැරදි අගයෙහි ප්‍රති result ලය වන “පංති නිදර්ශන නිර්මාණ ප්‍රකාශනය” ලෙස හැඳින්වේ) වම් අගයට (එය නමක් සහ නිශ්චිත වර්ගයක් සහිත යොමු විචල්‍යයකි) පවරා ඇත.

වස්තුවක යොමු කිරීම අගය අනුව සම්මත වුවද, ක්‍රමයකට තවමත් යොමු කරන ලද වස්තුව සමඟ අන්තර්ක්‍රියා කළ හැක්කේ එහි පොදු ක්‍රම ඇමතීමෙන් වස්තුවෙහි යොමු පිටපත භාවිතා කරමිනි. පරාමිතිය තුළ ගබඩා කර ඇති යොමු කිරීම තර්කයක් ලෙස සම්මත කරන ලද යොමු පිටපතක් බැවින්, කැඳවූ ක්‍රමයේ පරාමිතිය සහ ඇමතුම් ක්‍රමයේ පරාමිතිය මතකයේ ඇති එකම වස්තුවට යොමු වේ.

අරා වස්තූන් වෙනුවට අරා වෙත යොමු කිරීම කාර්ය සාධන හේතු සඳහා අර්ථවත් කරයි. ජාවා හි ඇති සෑම දෙයක්ම අගය මගින් සම්මත කර ඇති නිසා, අරාව වස්තු සම්මත කර ඇත්නම්, එක් එක් මූලද්‍රව්‍යයේ පිටපතක් ලබා දෙනු ඇත. විශාල අරා සඳහා, මෙය කාලය නාස්ති කරන අතර මූලද්‍රව්‍යවල පිටපත් සඳහා සැලකිය යුතු ගබඩා ප්‍රමාණයක් වැය කරයි.

පහත දැක්වෙන රූපයේ අපට යොමු විචල්‍යයන් දෙකක් ඇති බව දැකිය හැකිය (මේවා C / C ++ හි දර්ශක ලෙස හැඳින්වේ, තවද මෙම පදය මෙම අංගය තේරුම් ගැනීම පහසු කරයි.) ප්‍රධාන ක්‍රමයේදී. ප්‍රාථමික සහ විමර්ශන විචල්‍යයන් සිරස් මතකයේ තබා ඇත (පහත රූපවල වම් පැත්ත). අරාව 1 සහ අරා 2 විමර්ශන විචල්‍යයන් “ලක්ෂ්‍යය” (සී / සී ++ ක්‍රමලේඛකයන් එය හඳුන්වන පරිදි) හෝ පිළිවෙලින් a සහ b අරා වෙත යොමු කිරීම, ඒවා වස්තු (මෙම යොමු විචල්‍යයන් දරණ අගයන් වස්තු වල ලිපින වේ) ගොඩවල් මතකයේ (පහත රූපවල දකුණු පැත්ත) .

අගය උදාහරණ 1 පසු කරන්න

අපි අරාව 1 යොමු විචල්‍යයේ අගය ප්‍රතිවිකුණුම් ක්‍රමයට තර්කයක් ලෙස යොමු කළහොත්, ක්‍රමයේදී විමර්ශන විචල්‍යයක් නිර්මාණය වන අතර එම යොමු විචල්‍යය එකම අරාව (අ) වෙත යොමු වීමට පටන් ගනී.

public class Test
{
    public static void reverseArray(int[] array1)
    {
        // ...
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        reverseArray(array1);
    }
}

අගය උදාහරණ 2 පසු කරන්න

ඉතින්, අපි කිව්වොත්

array1[0] = 5;

ප්‍රතිලෝම අරා ක්‍රමයේදී, එය අරාවෙහි වෙනසක් සිදු කරයි a.

අපට අරාව වෙත යොමු වන ප්‍රතිලෝම ආරේ ක්‍රමයේ (අරාව 2) තවත් යොමු විචල්‍යයක් ඇත. අපි කිව්වොත්

array1 = array2;

ප්‍රතිලෝම අරේ ක්‍රමයේදී, ප්‍රතිලෝම අරේ ක්‍රමයේ යොමු විචල්‍යය අරාව a වෙත යොමු කිරීම නවතා c අරාව වෙත යොමු කිරීම ආරම්භ කරයි (දෙවන රූපයේ තිත් රේඛාව).

අපි ආපසු හැරවීමේ ක්‍රමයේ ප්‍රතිලාභ අගය ලෙස යොමු විචල්‍ය අරාව 2 හි අගය ආපසු ලබා දී මෙම ක්‍රමය ප්‍රධාන ක්‍රමයේදී විචල්‍ය විචල්‍ය අරාව 1 වෙත යොමු කළහොත්, ප්‍රධාන වශයෙන් අරාව 1 අරාව වෙත යොමු වීමට පටන් ගනී.

ඒ නිසා අපි දැන් කළ සියලු දේ එකවර ලියමු.

public class Test
{
    public static int[] reverseArray(int[] array1)
    {
        int[] array2 = { -7, 0, -1 };

        array1[0] = 5; // array a becomes 5, 10, -7

        array1 = array2; /* array1 of reverseArray starts
          pointing to c instead of a (not shown in image below) */
        return array2;
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        array1 = reverseArray(array1); /* array1 of 
         main starts pointing to c instead of a */
    }
}

රූප විස්තරය මෙහි ඇතුළත් කරන්න

දැන් එම ප්‍රතිලෝම අරා ක්‍රමය අවසන් වී ඇති බැවින් එහි යොමු විචල්‍යයන් (array1 සහ array2) නැති වී ඇත. එයින් අදහස් කරන්නේ අපට දැන් ඇත්තේ ප්‍රධාන ක්‍රමයේ අරාව 1 සහ අරා 2 හි පිළිවෙලින් සී සහ බී අරා වෙත යොමු වන යොමු විචල්‍යයන් දෙක පමණි. යොමු විචල්‍යයක් වස්තුව (අරාව) වෙත යොමු නොකරයි a. එබැවින් එය කසළ එකතු කිරීම සඳහා සුදුසුකම් ලබයි.

ඔබට ප්‍රධාන වශයෙන් අරාව 1 ට අරාව 2 හි අගය පැවරිය හැකිය. array1 b වෙත යොමු වීමට පටන් ගනී.


27

මම මෙහි ඕනෑම ක්‍රමලේඛන භාෂාවක් සඳහා මේ ආකාරයේ ප්‍රශ්න සඳහා කැප වූ ත්‍රෙඩ් එකක් නිර්මාණය කර ඇත්තෙමි .

ජාවා ද සඳහන් වේ. කෙටි සාරාංශය මෙන්න:

  • ජාවා එය පරාමිතීන් අගය අනුව සම්මත කරයි
  • "අගය අනුව" යනු ක්‍රමයකට පරාමිතියක් යැවීමට ජාවාහි ඇති එකම ක්‍රමයයි
  • පරාමිතිය ලෙස ලබා දී ඇති වස්තුවෙන් ක්‍රම භාවිතා කිරීමෙන් මුල් වස්තූන් වෙත යොමු යොමු වන පරිදි වස්තුව වෙනස් වේ. (එම ක්‍රමයම සමහර අගයන් වෙනස් කරන්නේ නම්)

27

දිගු කතාවක් කෙටියෙන් කිරීමට, ජාවා වස්තූන් සතුව ඉතා සුවිශේෂී ගුණාංග ඇත.

පොදුවේ ගත් කල, ජාවා ප්රාථමික වර්ග (ඇත int, bool, char, doubleඅගය විසින් සෘජුවම සම්මත කරන බව, ආදිය). එවිට ජාවාට වස්තූන් ඇත (සෑම දෙයක්ම ව්‍යුත්පන්න වේ java.lang.Object). වස්තූන් සැබවින්ම හසුරුවනු ලබන්නේ යොමු කිරීමක් හරහා ය (යොමු කිරීම ඔබට ස්පර්ශ කළ නොහැකි දර්ශකයක් වේ). එහි අර්ථය වන්නේ, යොමු කිරීම් සාමාන්‍යයෙන් සිත්ගන්නා සුළු නොවන බැවින්, වස්තූන් යොමු කිරීමෙනි. කෙසේ වෙතත් එයින් අදහස් වන්නේ යොමු කිරීම අගය මගින් සම්මත කර ඇති බැවින් ඔබට පෙන්වා ඇති වස්තුව වෙනස් කළ නොහැකි බවයි.

මෙය අමුතු හා ව්‍යාකූලද? C ක්‍රියාත්මක කිරීම යොමු කිරීම හා අගය අනුව ගමන් කරන්නේ කෙසේදැයි සලකා බලමු. C හි, පෙරනිමි සම්මුතිය අගය අනුව සම්මත වේ. void foo(int x)අගය අනුව int එකක් පසු කරයි. void foo(int *x)යනු අවශ්‍ය නොවන ශ්‍රිතයකි int a, නමුත් int ට දර්ශකයක් : foo(&a). &විචල්ය ලිපිනයක් යැවීමට යමෙකු මෙය ක්රියාකරු සමඟ භාවිතා කරයි .

මෙය C ++ වෙත ගෙන යන්න, එවිට අපට යොමු කිරීම් ඇත. යොමු කිරීම් මූලික වශයෙන් (මෙම සන්දර්භය තුළ) සමීකරණයේ දර්ශක කොටස සැඟවිය හැකි සින්ටැක්ටික් සීනි වේ: void foo(int &x)එය හැඳින්වෙන්නේ foo(a)සම්පාදකයා විසින්ම එය යොමු කිරීමක් බව දන්නා අතර යොමු නොකිරීමේ ලිපිනය aසම්මත කළ යුතුය. ජාවා හි, වස්තූන් වෙත යොමු කරන සියලුම විචල්‍යයන් සැබවින්ම විමර්ශන වර්ගයට අයත් වේ.


මම හිතන්නේ එය ජාවා වස්තුව පිළිබඳ මගේ අවබෝධයට හා එහි යොමු දැක්වීමට ඉතා සමීප ය. ජාවා හි වස්තුව යොමු කිරීමේ පිටපතක් (හෝ අන්වර්ථයක්) මඟින් ක්‍රමයකට යවනු ලැබේ.
මැක්ස් සූම්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.