计算机专业论文译文对象传递.docx
《计算机专业论文译文对象传递.docx》由会员分享,可在线阅读,更多相关《计算机专业论文译文对象传递.docx(53页珍藏版)》请在冰豆网上搜索。
计算机专业论文译文对象传递
专业译文
原文出处:
http:
//www.faqs.org/docs/think_java/TIJ319.htm
Passing&ReturningObjects
Bynowyoushouldbereasonablycomfortablewiththeideathatwhenyou’re“passing”anobject,you’reactuallypassingareference.
Inmanyprogramminglanguagesyoucanusethatlanguage’s“regular”waytopassobjectsaround,andmostofthetimeeverythingworksfine.Butitalwaysseemsthattherecomesapointatwhichyoumustdosomethingirregular,andsuddenlythingsgetabitmorecomplicated(orinthecaseofC++,quitecomplicated).Javaisnoexception,andit’simportantthatyouunderstandexactlywhat’shappeningasyoupassobjectsaroundandmanipulatethem.Thisappendixwillprovidethatinsight.
Anotherwaytoposethequestionofthisappendix,ifyou’recomingfromaprogramminglanguagesoequipped,is“DoesJavahavepointers?
”Somehaveclaimedthatpointersarehardanddangerousandthereforebad,andsinceJavaisallgoodnessandlightandwillliftyourearthlyprogrammingburdens,itcannotpossiblycontainsuchthings.However,it’smoreaccuratetosaythatJavahaspointers;indeed,everyobjectidentifierinJava(exceptforprimitives)isoneofthesepointers,buttheiruseisrestrictedandguardednotonlybythecompilerbutbytherun-timesystem.Ortoputitanotherway,Javahaspointers,butnopointerarithmetic.ThesearewhatI’vebeencalling“references,”andyoucanthinkofthemas“safetypointers,”notunlikethesafetyscissorsofelementaryschool—theyaren’tsharp,soyoucannothurtyourselfwithoutgreateffort,buttheycansometimesbeslowandtedious.
Passingreferencesaround
Whenyoupassareferenceintoamethod,you’restillpointingtothesameobject.Asimpleexperimentdemonstratesthis:
//:
appendixa:
PassReferences.java
//Passingreferencesaround.
importcom.bruceeckel.simpletest.*;
publicclassPassReferences{
privatestaticTestmonitor=newTest();
publicstaticvoidf(PassReferencesh){
System.out.println("hinsidef():
"+h);
}
publicstaticvoidmain(String[]args){
PassReferencesp=newPassReferences();
System.out.println("pinsidemain():
"+p);
f(p);
monitor.expect(newString[]{
"%%pinsidemain\\(\\):
PassReferences@[a-z0-9]+",
"%%hinsidef\\(\\):
PassReferences@[a-z0-9]+"
});
}
}///:
~
ThemethodtoString( )isautomaticallyinvokedintheprintstatements,andPassReferencesinheritsdirectlyfromObjectwithnoredefinitionoftoString( ).Thus,Object’sversionoftoString( )isused,whichprintsouttheclassoftheobjectfollowedbytheaddresswherethatobjectislocated(notthereference,buttheactualobjectstorage).Theoutputlookslikethis:
pinsidemain():
PassReferences@ad3ba4
hinsidef():
PassReferences@ad3ba4
Youcanseethatbothpandhrefertothesameobject.ThisisfarmoreefficientthanduplicatinganewPassReferencesobjectjustsothatyoucansendanargumenttoamethod.Butitbringsupanimportantissue.
Aliasing
Aliasingmeansthatmorethanonereferenceistiedtothesameobject,asintheprecedingexample.Theproblemwithaliasingoccurswhensomeonewritestothatobject.Iftheownersoftheotherreferencesaren’texpectingthatobjecttochange,they’llbesurprised.Thiscanbedemonstratedwithasimpleexample:
//:
appendixa:
Alias1.java
//Aliasingtworeferencestooneobject.
importcom.bruceeckel.simpletest.*;
publicclassAlias1{
privatestaticTestmonitor=newTest();
privateinti;
publicAlias1(intii){i=ii;}
publicstaticvoidmain(String[]args){
Alias1x=newAlias1(7);
Alias1y=x;//Assignthereference
System.out.println("x:
"+x.i);
System.out.println("y:
"+y.i);
System.out.println("Incrementingx");
x.i++;
System.out.println("x:
"+x.i);
System.out.println("y:
"+y.i);
monitor.expect(newString[]{
"x:
7",
"y:
7",
"Incrementingx",
"x:
8",
"y:
8"
});
}
}///
Intheline:
Alias1y=x;//Assignthereference
anewAlias1referenceiscreated,butinsteadofbeingassignedtoafreshobjectcreatedwithnew,it’sassignedtoanexistingreference.Sothecontentsofreferencex,whichistheaddressoftheobjectxispointingto,isassignedtoy,andthusbothxandyareattachedtothesameobject.Sowhenx’siisincrementedinthestatement:
x.i++;
y’siwillbeaffectedaswell.Thiscanbeseenintheoutput:
x:
7
y:
7
Incrementingx
x:
8
y:
8
Onegoodsolutioninthiscaseissimplynottodoit;don’tconsciouslyaliasmorethanonereferencetoanobjectatthesamescope.Yourcodewillbemucheasiertounderstandanddebug.However,whenyou’repassingareferenceinasanargument—whichisthewayJavaissupposedtowork—youautomaticallyalias,becausethelocalreferencethat’screatedcanmodifythe“outsideobject”(theobjectthatwascreatedoutsidethescopeofthemethod).Here’sanexample:
//:
appendixa:
Alias2.java
//Methodcallsimplicitlyaliastheirarguments.
importcom.bruceeckel.simpletest.*;
publicclassAlias2{
privatestaticTestmonitor=newTest();
privateinti;
publicAlias2(intii){i=ii;}
publicstaticvoidf(Alias2reference){reference.i++;}
publicstaticvoidmain(String[]args){
Alias2x=newAlias2(7);
System.out.println("x:
"+x.i);
System.out.println("Callingf(x)");
f(x);
System.out.println("x:
"+x.i);
monitor.expect(newString[]{
"x:
7",
"Callingf(x)",
"x:
8"
});
}
}///
Themethodischangingitsargument,theoutsideobject.Whenthiskindofsituationarises,youmustdecidewhetheritmakessense,whethertheuserexpectsit,andwhetherit’sgoingtocauseproblems.
Ingeneral,youcallamethodinordertoproduceareturnvalueand/orachangeofstateintheobjectthatthemethodiscalledfor.It’smuchlesscommontocallamethodinordertomanipulateitsarguments;thisisreferredtoas“callingamethodforitssideeffects.”Thus,whenyoucreateamethodthatmodifiesitsarguments,theusermustbeclearlyinstructedandwarnedabouttheuseofthatmethodanditspotentialsurprises.Becauseoftheconfusionandpitfalls,it’smuchbettertoavoidchangingtheargument.
Ifyouneedtomodifyanargumentduringamethodcallandyoudon’tintendtomodifytheoutsideargument,thenyoushouldprotectthatargumentbymakingacopyinsideyourmethod.That’sthesubjectofmuchofthisappendix.
Makinglocalcopies
Toreview:
AllargumentpassinginJavaisperformedbypassingreferences.Thatis,whenyoupass“anobject,”you’rereallypassingonlyareferencetoanobjectthatlivesoutsidethemethod,soifyouperformanymodificationswiththatreference,youmodifytheoutsideobject.Inaddition:
●Aliasinghappensautomaticallyduringargumentpassing.
●Therearenolocalobjects,onlylocalreferences.
●Referenceshavescopes,objectsdonot.
●ObjectlifetimeisneveranissueinJava.
●Thereisnolanguagesupport(e.g.,“const”)topreventobjectsfrombeingmodifiedandstopthenegativeeffectsofaliasing.Youcan’tsimplyusethefinalkeywordintheargumentlist;thatsimplypreventsyoufromrebindingthereferencetoadifferentobject.
Ifyou’reonlyreadinginformationfromanobjectandnotmodifyingit,passingareferenceisthemostefficientformofargumentpassing.Thisisnice;thedefaultwayofdoingthingsisalsothemostefficient.However,sometimesit’snecessarytobeabletotreattheobjectasifitwere“local”sothatchangesyoumakeaffectonlyalocalcopyanddonotmodifytheoutsideobject.Manyprogramminglanguagessupporttheabilitytoautomaticallymakealocalcopyoftheoutsideobject,insidethemethod.[116]Javadoesnot,butitallowsyoutoproducethiseffect.
Passbyvalue
Thisbringsuptheterminologyissue,whichalwaysseemsgoodforanargument.Thetermis“passbyvalue,”andthemeaningdependsonhowyouperceivetheoperationoftheprogram.Thegeneralmeaningisthatyougetalocalcopyofwhateveryou’repassing,buttherealquestionishowyouthinkaboutwhatyou’repassing.Whenitcomestothemeaningof“passbyvalue,”therearetwofairlydistinctcamps:
1.Javapasseseverythingbyvalue.Whenyou’repassingprimitivesintoamethod,yougetadistinctcopyoftheprimitive.Whenyou’repassingareferenceintoamethod,yougetacopyofthereference.Ergo,everythingispassbyvalue.Ofcourse,theassumptionisthatyou’realwaysthinking(andcaring)thatreferencesarebeingpassed,butitseemsliketheJavadesignhasgonealongwaytowardallowingyoutoignore(mostofthetime)thatyou’reworkingwithareference.Thatis,itseemstoallowyoutothinkofthereferenceas“theobject,”sinceitimplicitlydereferencesitwheneveryoumakeamethodcall.
2.Javapassesprimitivesbyvalue(noargumentthere),butobjectsarepassedbyreference.Thisistheworldviewthatthereferenceisanaliasfortheobject,soyoudon’tthinkaboutpassingreferences,butinsteadsay“I’mpassingtheobject.”Sinceyoudon’tgetalocalcopyoftheobjectwhenyoupassitintoamethod,objectsareclearlynotpassedbyvalue.ThereappearstobesomesupportforthisviewwithinSun,sinceatonetime,oneofthe“reservedbutnotimplemented”keywordswasbyvalue(Thiswillprobablyneverbeimplemented).
Havinggivenbothcampsagoodairing,andaftersaying“Itdependsonhowyouthinkofareference,”Iwillattempttosidesteptheissue.Intheend,itisn’tthatimportant—whatisimportantisthatyouunderstandthatpassingareferenceallowsthecaller’sobjecttobechangedunexpectedly.
Cloningobjects
Themostlikelyreasonformakingalocalcopyofanobjectisifyou’regoingtomodifythatobjectandyoudon’twanttomodifythecaller’sobject.Ifyoudecideth