Java混合编程资源小结
2004-07-05 19:29
489 查看
PuttingaJavaInterfaceonyourC,C++,orFortranCodeAbstract:ThepurposeofthisreportistodocumentsomeofthetechnicalaspectsofcreatingJavainterfacesforcodeswritteninlanguagesotherthanJava.Weoutlineaprocedurewhereoneseparatestheconstructionoftheinterfacefromtheexternalcodeswiththeintroductionofanintermediate"wrapper"class.Thisintermediateclassservestoisolateuserinterfacedetailsfromthedetailsofcallingexternalroutines.ThisintermediateclassalsofacilitatestheincorporationofexternalroutinesintoJavabasedsystemsfordistributedcomputingand/orvisualprogramming.ContentsChrisAndersonDepartmentofMathematicsUCLALosAngeles,CA915557/15/97ThesesoftwarecomponentsweredevelopedinconjunctionwiththeresearchsupportedbyAirForceOfficeofScientificResearchGrantF49620-96-I-0327andNationalScienceFoundation/ARPAGrantNSF-DMS-961584
IntroductionWhilepeoplearedebatingwhetherornotJavaisgoodforcomputationallyintensivetasks,thefactisthatC,C++andFortranaretheprimarylanguagesforthosewhodoscientific/technicalcomputing.Italsoseemsunlikelythatthissituationwillchangeinthenearfuture.Unfortunately,C,C++andFortrandonotcontain(asJavadoes)standardizedandplatformindependentconstructsforcreatinguserinterfaces,managingthreads,networking,andavarietyofothertasksassociatedwithcreating"applications".Thus,thereisinterestincreatingapplicationsinwhichtheuserinterface,orother"applicationpackaging",iswritteninJava,butthecorecomputationalcomponentiswritteninC,C++,orFortran(seeFigure1).Thepurposeofthisdocumentistodescribe,principallybymeansofanextendedexample,theprocessofcreatingaJavainterfaceforaprogramwritteninC,C++orFortran.InordertocreateapplicationswhichhavetheformindicatedinFigure1,oneneedstoknowhowtowriteJavainterfacesandhowtocallroutineswritteninC,C++andFortranfromJava.TheprocessofwritingaJavainterfaceiswelldescribedinavarietyofbooks[1][2][3][4]andwewillassumethatthereaderiscapableofwritingamodestJavainterfacewhichacceptsinputanddisplaysoutputtoauser.ThetaskofcallingroutineswritteninC,C++andFortranfromJavacomesundertheheadingofimplementingandusing"native"methods.Heretoo,otherdocuments[1][7]describetheprocessofinterfacingJavatootherlanguages.While,forcompleteness,wewilloutlinethestepsrequiredtocreateandimplementJavaclasseswithnativemethods,weassumethatthereaderhasimplementedaJavaclassthathasatleastonenativemethodprocedureinit(e.g.the"HelloWorld"exampleof[7]).Inoneaspect,thisreportisthepresentationofanextendedexampledemonstratinghowthisknowledgeofwritingJavainterfacesandimplementingnativemethodscanbecombinedtocreateaJava/"otherlanguage"application.Inadditiontoprovidingsamplesofthemechanismsfordataexchange,theexamplealsorevealsthechoiceswemade(andchoicesyouwillhavetomake)concerningthedividinglinebetweentheJavainterfaceandroutineswritteninC,C++orFortran.OurexampleconcernsthecreationofaJavainterfaceforaprogramwhichsolvestheheatequationinatwodimensionalrectangularregion.ExamplesinC++andFortranaregiven(asisreadilyseentheC++exampleisveryclosetowhatmightbecomposedinC).InthefirstsectionweoutlinetheprocessthatwefollowforcreatingapplicationsofthetypedescribedbyFigure1.Inthesecondsectionwepresenttheexamplewhichwillformthebasisofourdiscussion,andinthethirdandfourthsectionswedetailtheconstructionoftheJavaclasseswhichformtheprimarycomponentsoftheapplication.
TheprocessofcreatingaJavainterfacetoC,C++andFortranroutinesTheprocessthatweuseforcreatingJavainterfacesconsistsofthethreestepsindicatedinfigure2.Anoticeablefeatureoftheprocessisthatweutilizethreesteps,ratherthantwo.Onemaywonderabouttheneedfortheintermediatestep;thatofwritinganintermediateclassthat``wraps''theC,C++orFortrancode.Originallywedidn'thavethreesteps,butadoptedthispracticeforseveralreasons:Itfacilitatedhavingtheexternalcoderunasaseparatethread.Ifoneisrunningacomputationallyintensivetask,thenthisallowsthetasktobeexecutedwithout``freezing''theinterface.
Byusingthisintermediateclasswehaveisolatedthatcomponentoftheapplicationwhichcontainsinter-languagecalls.Sincetheinter-languagecallingprocedureforJavaisevolving,thisallowsustoaccommodateanychangesintheinter-languageproceduresmoreeasily.Additionally,bynotembeddingthiscodewithinauserinterface,wealsoallowtheuserinterfacetochangeindependently(thisisimportantbecausetheJavauserinterfaceclassesareevolvingaswell).
Lastly,andnolessimportantly,thisclassprovidesanencapsulationoftheexternalroutineswhichfacilitatestheirincorporationinavisualprogrammingsystemorasoftwareinfrastructurewhichsupportsdistributedcomputing.
Theexampleprogramwrittenin"another"language.ThestartingpointfortheprocessofwritingaJavainterfaceistohaveaprogramoraselectedsetofcodecomponentsthatonewishestowriteinterfacesfor.Ratherthandiscusstheprocessofwritinginterfacesinanabstractway,wediscusstheprocessofwritinginterfacesforaspecificexample.Theexampleprogramisonethatcomputestheevolutionofthetemperatureofarectangularplate.Themaindriverroutineisgivenbelow(aswellasinthefiletempCalc.cpp);theincludefileforthefunctionswhichthemainroutinecallsaregivenintempCalcRoutines.handthesourcefortheseroutinesisgivenintempCalcRoutines.cpp.Inthefirstpartofthemainroutine,theproblemandrunparametersareset,memoryisallocatedandthetemperaturedistributionisinitialized.Atimesteppingloopisthenexecuted.Inthisloop,thetemperatureoftheplateisevolvedintimeincrementsofsizedtbycallingtheroutineevolveTemperature(...)andatsomepredeterminednumberoftimestepsthetemperaturedistributionisoutput.(InthiscasewrittentoafiletempOut.dat).Eventhoughthetemperaturevaluesareassociatedwithatwo-dimensionalsetofnodescoveringtheplate,weallocateandpassone-dimensionalarraysofvalues.Thiswasdonebecausethestandardmethodforexchangingdatawithotherlanguagesisthroughone-dimensionalarrays;Javaisnoexception.Usingone-dimensionalsetsofdatavaluesdoesnotprecludeusingatwo-dimensionalarraystructuretoaccessthedata.Theroutinescreate2dArrayStructure(...)anddestroy2dArrayStructure(...)intempCalcRoutines.cppdemonstratehowonecancreateatwo-dimensionalarraystructurewhichaccessthedataallocatedasaonedimensionalarray.
#include<iostream.h>#include<fstream.h>#include"tempCalcRoutines.h"voidmain(){////SetProblemparameters//doublediffusivity=0.1;doublea=0.0;doubleb=1.0;doublec=0.0;doubled=1.0;////SetRuntimeparameters//longm=10;longn=20;longnSteps=100;longnOut=10;doubledt=0.01;////Allocatespaceforsolutionandworkarrays//double*Tarray=newdouble[m*n];double*workArray=newdouble[m*n];////Openoutputfile//ofstreamFout("tempOut.dat");initializeTemperature(Tarray,m,n,a,b,c,d);doubletime=0.0;inti;intj;for(i=1;i<=nSteps;i++){evolveTemperature(Tarray,m,n,a,b,c,d,dt,diffusivity,workArray);time=time+dt;if((i%nOut)==0){cout<<"Step"<<i<<endl;//printoutsteptoscreenFout<<m<<""<<n<<endl;//outputtofiletempOut.dat...Fout<<time<<endl;for(j=0;j<m*n;j++){Fout<<Tarray[j]<<endl;}}}delete[]Tarray;delete[]workArray;}Thisprogramistypicalofmanycomputationallyintensiveapplications;dataisallocated,parametersandvaluesareinitialized,andthenatimesteppingloopisexecuted.Asthecalculationproceedsdataisoutputperiodically.TheFortranversionofthisprogramisgivenintempCalc.fandthesupportingroutinesaregivenintempCalcRoutines.f.OnemaynoticethattheC++programisnearlyidenticaltotheFortranprogramanddoesnotuseanyoftheobjectorientedfeaturesofC++(i.e.itdoesnotutilizeclasses).Thiswasdoneintentionallysothatthecodewouldserveasanexampleofcodeswhicharelikelytobeused(and/orwritten)bythemajorityofthoseinvolvedinscientific/technicalcomputation.
TheJavaclassthatencapsulatestheC,C++orFortrancodescomponents.ThesecondstepintheprocessofcreatinganinterfaceistocreateaJavawrapperclassthatencapsulatestheC,C++orFortrancodecomponents.ItisinthisclassthattheconnectionbetweentheexternalroutinesandthecorrespondingJavaroutinesismade.Thisclassisalsoresponsiblefor"loading"theexternalroutines.Essentially,thisclassreplacesthemain()routine.Inthisregardtheclassallocatestherequiredarrays,containstheparametersasdatamembersandalsocontainsthemethods(declarednative)whichareinvokedbythemain()driverroutine(theinitializeTemperatureandevolveTemperatureroutines).Tofacilitatetheexecutionoftheprogramasaseparatethread,thisclassimplementstheRunnableinterface(itimplementsarun()method).Inthisrun()method,wehavechangedtheoutputprocesstobeonewhichdisplaysacolorcontourplotofthedata,ratherthanwritetheoutputtoafile.TherequisiteJavaclassesarecontainedinthefilesColorContourPlot.java,ColorContourCanvas.javaandContourResolutionDialog.java.Lastlythisroutinealsoincludesamainroutineofit'sownfortestingpurposes.ThecompletecodeisgiveninTempCalcJava.java.Sincethisroutinehasnativemethods,onemustcreatethedynamicallylinkedlibrary(DLL)orsharedlibrarythatcontainstheirimplementations.Asoutlinedinthediscussionsonimplementingnativemethods[1][7],thisisamulti-stepprocess:TheclassTempCalcJava.javaiscompiled.Eventhoughthenativemethodsarenotimplemented,youmustcompiletheJavaclasscontainingthenativemethodsbeforeperformingthenextstep.
ThecommandjavahisappliedtoTempCalcJava.class.Thismeansexecuting"javah-jniTempCalcJava".TheresultofthiscommandisthecreationofthefileTempCalcJava.h.SinceweareusingthenativeinterfacespecificationofJava1.1,thejavahcommandmustbetheonedistributedwiththeJDK1.1.
ThefunctionscontainedinTempCalcJava.hare"implemented".InthisregardourtaskconsistsofaccessingthedatacontainedwithintheJavaarraysandpassingittothecorrespondingC++(orFortranroutines).TheimplementationoftheseroutinesisgiveninTempCalcJava.cpp.(NotethatonecanselecttheFortranimplementationbydefining__FORTRAN_BUILD__inthecompilationprocess.)
TheroutinesinTempCalcJava.cppalongwiththoseintempCalcRoutines.cpparecompiledandadynamicallylinkedlibrary(orasharedlibrary)iscreated.Thenameofthislibrarymustcoincidewiththenameofthefile(withoutthe.dllor.soextension)whichoccursinSystem.loadorSystem.loadLibrarycommandwithinthestaticinitializerfortheclass.(ForsomenotesonthecompilationprocessseeNativeMethodCompilationNotes.)
See"NativeMethodImplementationProcess"foradiagramofthesesteps.Atthispoint,ifthenativemethodimplementationprocessissuccessful,oneshouldbeabletoruna"commandline"versionoftheprogrambyexecutingthemainroutineoftheclassi.e.justexecute"javaTempCalcJava".Problemswhichoccuratthispointareoftencausedbyincorrect,ornon-specification,ofthepathwhichissearchedforthelibrarycontainingthenativemethodimplementation.OnPC/WindowsplatformsthePATHvariablemustincludethedirectorycontainingthenativemethodimplementationdll.OnUNIXmachinesrunningsolaristheLD_LIBRARY_PATHvariablemustincludethedirectorycontainingthenativemethodimplementationsharedlibrary.
TheJavaInterfaceThethirdstepinwritingtheinterfaceistowritetheJavaclassthatimplementstheinterface.MinimallythismeanscreatingaJavaapplicationthatpossessesprogramcontrolbuttonsandfieldsfordatainput.Theinterfaceisdisplayedbelow,andtheassociatedJavacodeiscontainedwithinTemperatureApp.java.ThisuserinterfacewasconstructedusingtoolsthatgenerateJava1.0.2.However,sinceourimplementationofnativemethodsisJava1.1based,aftertheinitialconstruction,wecompiledandworkedwiththiscodeusingtheJava1.1compiler.IntheJava1.1compilationsteponemustspecifytheflag"-deprication"andputupwithallthewarningsthataregenerated.HopefullytheinterfaceconstructiontoolswillsupportJava1.1soonandthesenuisanceswilldisappear.InlookingovertheJavacode,oneshouldtakenotethatthecomputationallyintensivepartoftheapplicationisdoneasaseparatethread[6].Specifically,withinthecodewhichgetsexecutedwhentheRunbuttonishit(thecodefragmentisgivenbelow)wecreatethreadsfortheseparatecomponentsoftheapplication---onethreadforthecalculationcomponentandonethreadforthecolorcontourplot.Thecalculationcomponentthreadisgivenalowerpriority,sothatonmachineswhoseimplementationoftheJavavirtualmachinedoesn'ttime-sliceamongequalprioritythreads,thecomputationallyintensivecomponentwillnotcausetheuserinterfaceto"freeze".voidRunButton_Clicked(Eventevent){***////Setupandstartthethreadsforthecontourplotandthe//calculation//Threadcurrent=Thread.currentThread();//capturecurrentthreadThreadcontourThread=newThread(temperatureRun.contourPlot);contourThread.start();TempRunThread=newThread(temperatureRun);TempRunThread.setPriority(current.getPriority()-1);TempRunThread.start();}Thecolorcontourplotthatresultsfromtheexecutionoftheprogramisgivenbelow//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Java/FortranInterfaceThistutorialgivesanexampleofhowtointerfaceFortranandJava.ItisintendedtosupplementtheexamplegiveninJava/FortranInterfacetipsandit'sagoodideatoreadthatsitefirst.TheexamplewasdevelopedonSunSolarisusingSunWorkshop5.0C++andFortrancompilersandSunJDK1.2.Becausetheexampleisnolongerfullyportable,itmaynotworkonyoursystemandIdon'tknowenoughaboutothersystemstoreallyhelpyou.So,ifyoudomanagetogetthingsrunningonothersystemsthenpleasesendinyourtipsandmakefilesforthebenefitofotherusers.Whydoit?Javaprovidesobject-orientedprogramming,easyvisualisationandtrueportability.Fortranhasnoneofthesethingsbutdoesofferhighlyoptimisedcompilers(withtheoptionofparallelisation),excellentnumericallibraries,simplicity,mathssupport(e.g.complexnumbersandmulti-dimensionalarrays)andmassesoflegacycodeallofwhichmakeitexcellentfornumbercrunching.AlthoughonemightliketomoveovertopureJava,theperformanceadvantagesofFortranortheeffortofconvertinglegacycodeoftenenforcesadualapproachwithaninterfacebetweenthetwolanguages.IntroductionThistutorialwillworkthroughanexamplewhichsetssomevariablesinJava,changestheminFortranandshowstheeffectinJava.TheJavaprogrammustcalltheFortransubroutineviaaC++wrapper(asexplainedinJava/FortranInterfacetips)becauseJavacanonlytalktoCorC++.Thevariablesareintegers,doubles,booleansandstrings,oneofeachwiththesuffix"_A"andonewiththesuffix"_B".EachvariablewillbesetinJavaandresetinFortran.However,onlythechangesinthe"_A"variablesarepassedthroughtoJavaviatheC++wrapper.Inadditiontwo2-Darrays(adoubleprecisionarrayandacomplexdoubleprecisionarray)arepassedtoFortran.ThesearraysareoverwrittenintheFortransubroutine.BecauseJavadoesnotsupportmulti-dimensionalarrays,a2-Darrayofsize(mx,my)isreferencedasa1-Darreyofsize(mx*my).Inaddition,Javadoesnotsupportcomplexnumberssoa2-Dcomplexarrayofsize(mx,my)isreferencedasa1-Darrayofsize(2*mx*my).TheJavaprogramTheJavaprograminitialisesthevariablesandechoesthemtothescreen,thencallstheFortransubroutinethroughitsC++wrapperandechoestheupdatedvariablevalues.Inthelinepublicnativevoidcppsub(intint_A,intint_B,doubledouble_A,doubledouble_B,booleanbool_A,booleanbool_B,intmx,intmy,double[]doubleArray,double[]complexArray,Stringstring_A,Stringstring_B);wedeclareanativeroutine"cppsub"(ourC++wrapper).Inthelinestatic{System.loadLibrary("JniDemo");}weloadinthedynamiclibrary"libJniDemo.so".TheJavacodeiscompiledby"javacJniDemo.java"andisfoundhere:JniDemo.java.Noticehowthe1-DJavaarraysareunpackedtoaccessthe2-DFortranarrays.JavaincludefileWecanautomaticallygenerateaJavaincludefileforthenativeroutine"cppsub"fromJniDemo.classbytyping"javah-jniJniDemo".Theincludefileisfoundhere:JniDemo.h.andgivesusthedeclarationofthesubroutine"Java_JniDemo_cppsub"fortheC++wrapper.AlltheJavaintegers,doublesetc.havebeenpassedasC++typesjint,jdoubleetc.specifiedin"jni.h".TheC++wrapperTheC++wrapperistheheartoftheinterfaceandmustdomorethansimplypassitsparameterstoFortran.ThelinkbetweenFortranandC++isunfortunatelynotstandardised.InformationontheSolarisinterfaceisfoundhere:Fortran/CInterface.Thelineextern"C"voidf90sub_(int*int_A,int*int_B,double*double_A,double*double_B,unsignedchar*bool_A,unsignedchar*bool_B,int*mx,int*my,double*doubleArray,double*complexArray,constchar*str_A,constchar*str_B,int*str_A_len,int*str_B_len);declarestheexternallycompiledFortransubroutine"f90sub"whichgetsanunderscoreaddedtoitsname.Theroutineiscalledwith:f90sub_(&int_A,&int_B,&double_A,&double_B,&bool_A,&bool_B,&mx,&my,daPtr,caPtr,str_A,str_B,&str_A_len,&str_B_len);Allthevariablesarepassedbyreference.NotethatthejbooleansmustbepassedtoFortranastypeunsignedchar.Letusfirstlookatthescalarvariables(jint,jdouble,jboolean).ThesecansimplybepassedbyreferencetoFortran.OnreturnfromtheFortransubroutine,thecorrespondingJavavariablesendingin"_A"areupdatedby:jclasscls=env->GetObjectClass(obj);
jfieldIDfid;
....
fid=env->GetFieldID(cls,"int_A","I");
if(fid==0){
return;
}
env->SetIntField(obj,fid,int_A);
fid=env->GetFieldID(cls,"double_A","D");
if(fid==0){
return;
}
env->SetDoubleField(obj,fid,double_A);
fid=env->GetFieldID(cls,"bool_A","Z");
if(fid==0){
return;
}
env->SetIntField(obj,fid,bool_A);wherewedirectlyoverwritethevariables"int_A","double_A"and"bool_A"inthecallingobject"obj".Forthearrays,wecreatepointerstothosearraysbycallingaJNIroutine"GetDoubleArrayElements"andpassthosetotheFortransubroutine.BeforeleavingtheC++wrapperwemustcall"ReleaseDoubleArrayElements"incaseJavahadtomakeacopyofthearray(seeJavaNativeInterfacetutorial).jdouble*caPtr=env->GetDoubleArrayElements(complexArray,0);
jdouble*daPtr=env->GetDoubleArrayElements(doubleArray,0);
...
env->ReleaseDoubleArrayElements(complexArray,caPtr,0);
env->ReleaseDoubleArrayElements(doubleArray,daPtr,0);Passingstringsisslightlymorecomplicated.Wefirstdefinepointers"str_A"and"str_B"andgetthelengthsofthestringsusing"GetStringUTFChars"and"GetStringLength"andpassthosetoFortran:jstringjstr;
intstr_A_len,str_B_len;
constchar*str_A=env->GetStringUTFChars(string_A,0);
str_A_len=env->GetStringLength(string_A);
constchar*str_B=env->GetStringUTFChars(string_B,0);
str_B_len=env->GetStringLength(string_B);Nextwemakeacopyofthestring"str_A"toensureitisonly"str_A_len"characterslong:charbuf[128]="";
strncat(buf,str_A,str_A_len);Nowwecreatethejstring"jstr"usingtheJNImethod"NewStringUTF"andusethattooverwritetheJavastring"string_A"inthecallingprogram:fid=env->GetFieldID(cls,"string_A","Ljava/lang/String;");
if(fid==0){
return;
}
jstr=env->NewStringUTF(buf);
env->SetObjectField(obj,fid,jstr);Finally,wemustreleasethestringelements:env->ReleaseStringUTFChars(string_A,str_A);
env->ReleaseStringUTFChars(string_B,str_B);HereistheC++wrappercode:JniDemo.cppInSolaris,theC++wrapperiscompiledtocreatethedynamiclibrary"JniDemo.so"somethinglike:CC-G-I/usr/java/include-I/usr/java/include/solaris-oJniDemo.soJniDemo.cppTheFortransubroutineTheFortransubroutinefirstprintsoutallthevariablespassedtoit,thenoverwritesthemallandfinallyprintsoutthevariablesagain.Notethatbooleans(Fortranlogicals)mustbeconvertedfromtheunsignedcharsthatwerepassedfromtheC++wrapperwiththelines:bool_A=(cbool_A.eq.char(1))
bool_B=(cbool_B.eq.char(1))Attheend,theFortranlogicalsmustbeconvertedbacktounsignedcharacterswiththelines:cbool_A=char(0)
cbool_B=char(0)
if(bool_A)cbool_A=char(1)
if(bool_B)cbool_B=char(1)ThepassingsofcharacterstringsbetweenC++andFortranisnotstandardisedsowehaveusedcharacterarraysandpassedaseparateintegerwiththestringlength.ThearraysareindexedinthenormalFortranfashion.Thefortransubroutineisfoundhere:JniDemo_fortran.fInSolaris,wecompilethefortransubroutineandlinkintheC++wrapperlikethis:f90-lF77_mt-lM77-lfsu-lf77compat-G-L/usr/java/jre/lib/sparc-ljava-I/usr/java/include-I/usr/java/include/solaris-olibJniDemo.soJniDemo.soJniDemo_fortran.fThemakefileHereisthemakefileforSunSolaris:makefile.Itishopefullyeasytoadapttoyoursystem.Notethatfileswiththesuffix".so"aredynamiclibraries(equivalentto".DLL"filesinWindows).The"-G"compilerflagsignalscreationofadynamiclibrary.The"-o"flagnamestheoutputfile.The"-I"flagsignalsincludefiles.The"-L"flagsignalsthedirectorywherelibrariestobelinkedtoarekeptandthe"-l"flagnamesindividuallibraries(thenamesareexpandede.g.-ljavaindicatesfilelibjava.so).Here,dynamiclibrariesareusedthroughoutratherthanobjectfiles.ThefinallinkingstepmustbedonewiththeFortranf90compilersothedynamiclibrary"libJniDemo.so"iscreatedbylinkingthelibraries"JniDemo.so"andJniDemo_fortran.so"together.OutputoftheprogramCompiletheprogramusing"make"andrunitusing"javaJniDemo".Youshouldgettheoutputshownhere:Outputof"javaJniDemo".Notethattheprintstatementsmaybejumbledasyoushouldn'treallymixJavaandnativeinput/output.Ihopeyougotittowork.Nowtryadaptingittosuityourneeds.Ifthere'sanythingthathasn'tbeencoveredthenletmeknowattheaddressbelow.Goodluck!NotesThereseemstobeaproblem(usingSun/Solaris/Workshop)whenusinge.g.REAL(8)andCOMPLEX(16)inFortran90insteadofREAL*8andCOMPLEX*16.Igetthemessage:
FATALERRORinnativemethod:Trytounpinanobjectthatisnotpinned
Idon'tknowwhythisisandtheworkaroundistojustusetheREAL*8notation.Pleaseemailmeifyouknowwhat'sgoingon...//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Thepopularityofscriptingisgrowingfast!
Pythonistheveryhigh-levelJava,
Perlisverythehigh-levelC?
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////dynamically-typedlanguage,andthisfeatureisanimportantreasonwhyprogrammerscanbemoreproductivewithPython;theydon'thavetodealwiththeoverheadofJava'sstatictyping.SothedebatesaboutJava/Pythonproductivityinevitablyturnintodebatesaboutthecomparativeadvantagesanddrawbacksofstatictypingversusdynamictypinga€”orstrongtypingversusweaktypinga€”inprogramminglanguages.Iwillnotdiscussthatissuehere,otherthantonotethatinthelastfiveyearsanumberofinfluentialvoicesintheprogrammingcommunityhavebeenexpressingseriousdoubtsaboutthesupposedadvantagesofstatictyping.Forthosewhowishtopursuethematter,StrongversusWeakTyping:AConversationwithGuidovanRossum,PartVisagoodplacetostart.SeealsoBruceEckel'sweblogdiscussionStrongTypingvs.StrongTestingandRobertC.Martin'sweblogdiscussionAreDynamicLanguagesGoingtoReplaceStaticLanguages?.Forbackground,seeoneofthepapersthatstarteditallin1998—Scripting:HigherLevelProgrammingforthe21stCenturybyJohnOusterhout.SeveralofthesediscussionscontainvaluablecomparisonsofJavaandPython.Forotherlanguagecomparisons,seethePythonlanguagecomparisonspageatwww.python.org,andthePythonComparedToJavapageatPythonforJavaProgrammers.Finally,itisimportanttonotethatassertingthataprogrammercanbemoreproductiveinPythonthaninJava,isnotthesameasassertingthatoneoughtalwaystousePythonandnevertouseJava.Programminglanguagesaretools,anddifferenttoolsareappropriatefordifferentjobs.Itisapoorworkmanwhosetoolboxcontainsonlyahammer(nomatterhowbigitis!),anditisapoorprogrammer(orsoftwaredevelopmentorganization)whosedevelopmenttoolkitcontainsonlyoneprogramminglanguage.OurtoolboxesshouldcontainbothPythonandJava,sothatinanygivensituationwehavetheoptionofchoosingthebesttoolforthejob.SoourclaimisnotthatPythonistheonlyprogramminglanguagethatyou'lleverneed—onlythatthenumberofjobsforwhichPythonisthebesttoolismuchlargerthanisgenerallyrecognized.
ThereasonforthisisthatJava,virtuallyaloneamongobject-orientedprogramminglanguages,usescheckedexceptions—exceptionsthatmustbecaughtorthrownbyeverymethodinwhichtheymightappear,orthecodewillfailtocompile.Recently(asofJune2003)thereseemstobeanincreasingamountofunhappinesswithJava'suseofcheckedexceptions.SeeBruceEckel's"DoesJavaneedCheckedExceptions?"andRonWaldhoff's"Java'scheckedexceptionswereamistake".Aschromatic,theTechnicalEditoroftheO'ReillyNetwork,putit:WhyPython?EricS.Raymondnotesthat:Python...iscompact--youcanholditsentirefeatureset(andatleastaconceptindexofitslibraries)inyourhead.InWhyILovePythonBruceEckelnotesthatJavaisnotcompact.IcanremembermanyPythonidiomsbecausethey'resimpler.That'sonemorereasonIprogramfaster[inPython].IstillhavetolookuphowtoopenafileeverytimeIdoitinJava.Infact,mostthingsinJavarequiremetolooksomethingup.
Inparticular,thisexampleillustratestheclumsinessofcontainerobjectsinJava,whichrequirecastinganobjectwheneveritisextractedfromacontainer.ItisacommonpracticeamongJavaprogrammerstoovercomethisclumsinessbywritingapplication-specificcontainerobjectstowrapJava'sgenericcontainers.Youmight,forexample,haveanEmployeesclasstowrapavectorofEmployeeobjects.Theget()methodoftheEmployeesobjectwouldretrievetheappropriatememberoftheVector,andcastitbacktoanEmployeeobjectbeforereturningit.ThisisactuallyagoodpracticeinJava.Butithastheeffectofincreasingthenumberofclassesintheapplication--classesthattheprogrammermustwrite--and(becauseeachJavaclassmustexistinitsownfile)itincreasesthenumberofJavafilesthattheprogrammermustmanage.Noneofthis,ofcourse,isnecessaryinPython.TheburdenonJavaprogrammerswillbeeasedsomewhatinJava1.5withtheintroductionofgenericsandboxingconversions,alsoknowasautoboxing.
Omittingorduplicatingsuchcharactersiseasytodoaccidentally,andconstitutesasevereerrorinthecode.Inmypersonalestimate,Ispend5timesasmuchtimefixingsucherrorsinJavaasIdoinPython.Itreallycutsintoyourproductivity--andyourcreativeenergy--whenyouspendthatmuchofyourtimejusttryingtosatisfythecompiler.Technically,PythonhasanothercontrolcharacterthatJavadoesnota€”indentation.ButtherequirementforcorrectindentationisthesameinJavaasitisinPython,becauseinbothlanguagescorrectindentationisapracticalrequirementforhuman-readablecode.ThePythoninterpreterautomaticallyenforcescorrectindentation,whereastheJavacompilerdoesnot.WithJava,youneedanadd-onproductsuchastheJalopycodeformattertoprovideautomatedenforcementofindentationstandards.APPENDIX:Aboutstaticvs.dynamictyping,andstrongvs.weaktyping,ofprogramminglanguages.[/b]Thereiswidespreadconfusionordisagreementaboutthemeaningsofthewordsstatic,dynamic,strongandweakwhenusedtodescribethetypesystemsofprogramminglanguages.Whatfollowsisadescriptionoftheway(oratleastoneoftheways)thesetermsaremostcommonlyused.
Hereisanexample.Inastatically-typedlanguage,thefollowingsequenceofstatements(whichbindsanintegerobject,thenastringobject,tothenameemployeeName)isillegal.IfemployeeNamehadbeendeclaredtobeanint,thenthesecondstatementwouldbeillegal;ifithadbeendeclaredtobeaString,thenthefirststatementwouldbeillegal.Butinadynamically-typedlanguagethissequenceofstatementsisperfectlyfine.
Pythonisadynamically-typedlanguage.Javaisastatically-typedlanguage.Inaweaklytypedlanguage,variablescanbeimplicitlycoercedtounrelatedtypes,whereasinastronglytypedlanguagetheycannot,andanexplicitconversionisrequired.(NotethatIsaidunrelatedtypes.Mostlanguageswillallowimplicitcoercionsbetweenrelatedtypesa€”forexample,theadditionofanintegerandafloat.ByunrelatedtypesImeanthingslikenumbersandstrings.)Inatypicalweaklytypedlanguage,thenumber9andthestring"9"areinterchangeable,andthefollowingsequenceofstatementsislegal.
Inastronglytypedlanguage,ontheotherhand,thelasttwostatementswouldraisetypeexceptions.Toavoidtheseexceptions,somekindofexplicittypeconversionwouldbenecessary,likethis.
BothJavaandPythonarestronglytypedlanguages.ExamplesofweaklytypedlanguagesarePerlandRexx.Athirddistinctionmaybemadebetweenmanifestlytypedlanguagesinwhichvariablenamesmusthaveexplicittypedeclarations,andimplictlytypedlanguagesinwhichthisisnotrequired.Moststaticlanguagesarealsomanifestlytyped(Javacertainlyis),butFrankMitchellnotesthatsomearenot:"HaskellandthedialectsofML,forexample,caninferthetypeofanyvariablebasedontheoperationsperformedonit,withonlyoccasionalhelpfromanexplicittype."////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////JavaPython Usedtobe"JPython",namerecentlychangedto"jython".AnimplementationofthePythonLanguagethatgeneratesbytecodesfortheJavavirtualmachine.http://www.jython.org/
fromthesite...(somefromanoldersite)Jythonisanimplementationofthehigh-level,dynamic,object-orientedPythonLanguagewrittenin100%PureJava,andseamlesslyintegratedwiththeJavaplatform.ItthusallowsyoutorunPythononanyJavaplatform.Jythonisfreelyavailableforbothcommercialandnon-commercialuseandisdistributedwithsourcecode.JythoniscomplementarytoJavaandisespeciallysuitedforthefollowingtasks:Embeddedscripting-JavaprogrammerscanaddtheJPythonlibrariestotheirsystemtoallowenduserstowritesimpleorcomplicatedscriptsthataddfunctionalitytotheapplication.SinceJPythoniscertified100%PureJava,itcanbeaddedtoanapplicationwithoutfearofcompromisingitsabilitytorunonallJavaplatforms.
Interactiveexperimentation-JythonprovidesaninteractiveinterpreterthatcanbeusedtointeractwithJavapackagesorwithrunningJavaapplications.ThisallowsprogrammerstoexperimentanddebuganyJavasystemusingJython.
Rapidapplicationdevelopment-PythonLanguageprogramsaretypically2-10XshorterthantheequivalentJavaprogram.Thistranslatesdirectlytoincreasedprogrammerproductivity.TheseamlessinteractionbetweenPythonLanguageandJavaallowsdeveloperstofreelymixthetwolanguagesbothduringdevelopmentandinshippingproducts.
Strengths:Abilitytouseascriptinglanguagefromwithinjava.Thisalonemakesitworthwhile!
ExcellentabilitytoinvokeJavaobjectsfromPythoncode.Thismeansthatyouhaveeasyaccesstoallthosejavalibraries.Infact,it'softenEASIERtocalljavaobjectsfromthePythonsidethanfromthejavaside!Theonlytimeitgetsannoyingiswhentherearemultiplemethodswiththesamenamebutmultiplesignatures.
PrettydarneasytoinvokePythonobjectsfromJavacode.Thislessused,butvitallyimportantforcompleteintegration.
Allthe"obvious"conversionsareperformedforyou.Strings,numbers,arrays,andthingslikethataretypicallyconvertedforyouwithlittleeffort.Ajava.lang.StringjustbecomesaPythonstring(andvice-versa)withnoneedto"convert".Withfancierobjectsyou'llneedtomakesomeeffort.
PythoninterpretercaneasilybeembeddedinJava.Theexistanceof"exec"(orit'sequivalent)inPerlLanguage,PythonLanguage,LispLanguage,etcmakesitquiteeasytomakethingsuser-scriptable(atruntime).NowyoucandoitforJavaLanguagetoo,onlytheuserscriptsgetwritteninpython.
Weaknesses:Classloadingisweak.Forexample,ifyouchangeascript,youeitherneedtorunitwithanewclassloaderorrestarttheapplicationthatwillexecthescript.Furthermore,reloadisshallow,soifanyimportedscriptschange,theyalsoneedtoberecompiledandrununderanewclassloader.
JythonprogramsrunmuchmoreslowlythanCPythonones.
JythonisaboutonetenthofaversionorsobehindCPython,plusitdoesn'thaveallthesamelibrariesandfunctionalityasCPython.
Javaarraysareaproblem.UsethejarraymoduleforJavaarraysupport.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MarcelOliver,LouisLuangNumPyisasetofnumericalextensionsforPythonthatintroducesamultidimensionalarraytypeandarichsetofmatrixoperationsandmathematicalfunctions.UserswhohaveMATLAB5installed,however,maywishtotakeadvantageofsomeofMATLAB'sadditionalfunctions,includingtheplottinginterface.ThePyMatmoduleactsasaninterfacebetweenNumPyarraysinPythonandaMATLABenginesession,allowingarraystobepassedbackandforthandarbitrarycommandstobeexecutedintheMATLABworkspace.PyMatisusableonbothUNIXandWin32platforms,althoughtherearesomeslightdifferencesbetweenthetwo(mainlyduetoMATLAB'slimitations).YoucandownloadthelatestversionofPyMatfrom:
APythonlistortuplecontainingnumericvalues.Inthiscase,aNumPyobjectiscreatedfromthelistortuple(asifyouwereusingNumPy's
APythonstringobject.Inthiscase,aMATLABcharacterarraywillbeinstantiatedwiththecontentsofthestring.
TheWin32platformdoesnotsupportretrievingcharacterstringsfromtheMATLABworkspace.
Simplyplacethe
IntroductionWhilepeoplearedebatingwhetherornotJavaisgoodforcomputationallyintensivetasks,thefactisthatC,C++andFortranaretheprimarylanguagesforthosewhodoscientific/technicalcomputing.Italsoseemsunlikelythatthissituationwillchangeinthenearfuture.Unfortunately,C,C++andFortrandonotcontain(asJavadoes)standardizedandplatformindependentconstructsforcreatinguserinterfaces,managingthreads,networking,andavarietyofothertasksassociatedwithcreating"applications".Thus,thereisinterestincreatingapplicationsinwhichtheuserinterface,orother"applicationpackaging",iswritteninJava,butthecorecomputationalcomponentiswritteninC,C++,orFortran(seeFigure1).Thepurposeofthisdocumentistodescribe,principallybymeansofanextendedexample,theprocessofcreatingaJavainterfaceforaprogramwritteninC,C++orFortran.InordertocreateapplicationswhichhavetheformindicatedinFigure1,oneneedstoknowhowtowriteJavainterfacesandhowtocallroutineswritteninC,C++andFortranfromJava.TheprocessofwritingaJavainterfaceiswelldescribedinavarietyofbooks
TheprocessofcreatingaJavainterfacetoC,C++andFortranroutinesTheprocessthatweuseforcreatingJavainterfacesconsistsofthethreestepsindicatedinfigure2.Anoticeablefeatureoftheprocessisthatweutilizethreesteps,ratherthantwo.Onemaywonderabouttheneedfortheintermediatestep;thatofwritinganintermediateclassthat``wraps''theC,C++orFortrancode.Originallywedidn'thavethreesteps,butadoptedthispracticeforseveralreasons:Itfacilitatedhavingtheexternalcoderunasaseparatethread.Ifoneisrunningacomputationallyintensivetask,thenthisallowsthetasktobeexecutedwithout``freezing''theinterface.
Byusingthisintermediateclasswehaveisolatedthatcomponentoftheapplicationwhichcontainsinter-languagecalls.Sincetheinter-languagecallingprocedureforJavaisevolving,thisallowsustoaccommodateanychangesintheinter-languageproceduresmoreeasily.Additionally,bynotembeddingthiscodewithinauserinterface,wealsoallowtheuserinterfacetochangeindependently(thisisimportantbecausetheJavauserinterfaceclassesareevolvingaswell).
Lastly,andnolessimportantly,thisclassprovidesanencapsulationoftheexternalroutineswhichfacilitatestheirincorporationinavisualprogrammingsystemorasoftwareinfrastructurewhichsupportsdistributedcomputing.
Theexampleprogramwrittenin"another"language.ThestartingpointfortheprocessofwritingaJavainterfaceistohaveaprogramoraselectedsetofcodecomponentsthatonewishestowriteinterfacesfor.Ratherthandiscusstheprocessofwritinginterfacesinanabstractway,wediscusstheprocessofwritinginterfacesforaspecificexample.Theexampleprogramisonethatcomputestheevolutionofthetemperatureofarectangularplate.Themaindriverroutineisgivenbelow(aswellasinthefile
#include<iostream.h>#include<fstream.h>#include"tempCalcRoutines.h"voidmain(){////SetProblemparameters//doublediffusivity=0.1;doublea=0.0;doubleb=1.0;doublec=0.0;doubled=1.0;////SetRuntimeparameters//longm=10;longn=20;longnSteps=100;longnOut=10;doubledt=0.01;////Allocatespaceforsolutionandworkarrays//double*Tarray=newdouble[m*n];double*workArray=newdouble[m*n];////Openoutputfile//ofstreamFout("tempOut.dat");initializeTemperature(Tarray,m,n,a,b,c,d);doubletime=0.0;inti;intj;for(i=1;i<=nSteps;i++){evolveTemperature(Tarray,m,n,a,b,c,d,dt,diffusivity,workArray);time=time+dt;if((i%nOut)==0){cout<<"Step"<<i<<endl;//printoutsteptoscreenFout<<m<<""<<n<<endl;//outputtofiletempOut.dat...Fout<<time<<endl;for(j=0;j<m*n;j++){Fout<<Tarray[j]<<endl;}}}delete[]Tarray;delete[]workArray;}Thisprogramistypicalofmanycomputationallyintensiveapplications;dataisallocated,parametersandvaluesareinitialized,andthenatimesteppingloopisexecuted.Asthecalculationproceedsdataisoutputperiodically.TheFortranversionofthisprogramisgivenin
TheJavaclassthatencapsulatestheC,C++orFortrancodescomponents.ThesecondstepintheprocessofcreatinganinterfaceistocreateaJavawrapperclassthatencapsulatestheC,C++orFortrancodecomponents.ItisinthisclassthattheconnectionbetweentheexternalroutinesandthecorrespondingJavaroutinesismade.Thisclassisalsoresponsiblefor"loading"theexternalroutines.Essentially,thisclassreplacesthemain()routine.Inthisregardtheclassallocatestherequiredarrays,containstheparametersasdatamembersandalsocontainsthemethods(declarednative)whichareinvokedbythemain()driverroutine(theinitializeTemperatureandevolveTemperatureroutines).Tofacilitatetheexecutionoftheprogramasaseparatethread,thisclassimplementstheRunnableinterface(itimplementsarun()method).Inthisrun()method,wehavechangedtheoutputprocesstobeonewhichdisplaysacolorcontourplotofthedata,ratherthanwritetheoutputtoafile.TherequisiteJavaclassesarecontainedinthefiles
ThecommandjavahisappliedtoTempCalcJava.class.Thismeansexecuting"javah-jniTempCalcJava".Theresultofthiscommandisthecreationofthefile
Thefunctionscontainedin
Theroutinesin
See"
TheJavaInterfaceThethirdstepinwritingtheinterfaceistowritetheJavaclassthatimplementstheinterface.MinimallythismeanscreatingaJavaapplicationthatpossessesprogramcontrolbuttonsandfieldsfordatainput.Theinterfaceisdisplayedbelow,andtheassociatedJavacodeiscontainedwithin
jfieldIDfid;
....
fid=env->GetFieldID(cls,"int_A","I");
if(fid==0){
return;
}
env->SetIntField(obj,fid,int_A);
fid=env->GetFieldID(cls,"double_A","D");
if(fid==0){
return;
}
env->SetDoubleField(obj,fid,double_A);
fid=env->GetFieldID(cls,"bool_A","Z");
if(fid==0){
return;
}
env->SetIntField(obj,fid,bool_A);wherewedirectlyoverwritethevariables"int_A","double_A"and"bool_A"inthecallingobject"obj".Forthearrays,wecreatepointerstothosearraysbycallingaJNIroutine"GetDoubleArrayElements"andpassthosetotheFortransubroutine.BeforeleavingtheC++wrapperwemustcall"ReleaseDoubleArrayElements"incaseJavahadtomakeacopyofthearray(see
jdouble*daPtr=env->GetDoubleArrayElements(doubleArray,0);
...
env->ReleaseDoubleArrayElements(complexArray,caPtr,0);
env->ReleaseDoubleArrayElements(doubleArray,daPtr,0);Passingstringsisslightlymorecomplicated.Wefirstdefinepointers"str_A"and"str_B"andgetthelengthsofthestringsusing"GetStringUTFChars"and"GetStringLength"andpassthosetoFortran:jstringjstr;
intstr_A_len,str_B_len;
constchar*str_A=env->GetStringUTFChars(string_A,0);
str_A_len=env->GetStringLength(string_A);
constchar*str_B=env->GetStringUTFChars(string_B,0);
str_B_len=env->GetStringLength(string_B);Nextwemakeacopyofthestring"str_A"toensureitisonly"str_A_len"characterslong:charbuf[128]="";
strncat(buf,str_A,str_A_len);Nowwecreatethejstring"jstr"usingtheJNImethod"NewStringUTF"andusethattooverwritetheJavastring"string_A"inthecallingprogram:fid=env->GetFieldID(cls,"string_A","Ljava/lang/String;");
if(fid==0){
return;
}
jstr=env->NewStringUTF(buf);
env->SetObjectField(obj,fid,jstr);Finally,wemustreleasethestringelements:env->ReleaseStringUTFChars(string_A,str_A);
env->ReleaseStringUTFChars(string_B,str_B);HereistheC++wrappercode:
bool_B=(cbool_B.eq.char(1))Attheend,theFortranlogicalsmustbeconvertedbacktounsignedcharacterswiththelines:cbool_A=char(0)
cbool_B=char(0)
if(bool_A)cbool_A=char(1)
if(bool_B)cbool_B=char(1)ThepassingsofcharacterstringsbetweenC++andFortranisnotstandardisedsowehaveusedcharacterarraysandpassedaseparateintegerwiththestringlength.ThearraysareindexedinthenormalFortranfashion.Thefortransubroutineisfoundhere:
FATALERRORinnativemethod:Trytounpinanobjectthatisnotpinned
Idon'tknowwhythisisandtheworkaroundistojustusetheREAL*8notation.Pleaseemailmeifyouknowwhat'sgoingon...//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WhynotsticktoJavaorC/C++?
FeaturesofPerlandPythoncomparedwithJava,C/C++andFortran:shorterprograms | |
muchfasterdevelopment | |
novariabledeclarations, butlotsofconsitencychecksatruntime | |
lotsofgluingtools | |
lotsoftextprocessingtools | |
GUIsaresimpler/shorter | |
lotsofWebprogrammingtools |
Scriptingisontherise
70s/80s:Unixshell,jobcontrollanguages(primitive,crypticprogramming) | |
90s:DevelopmentofPerl,Python,Ruby,Tcl++ | |
Y2K:Scriptinglanguagesarestableandpowerfulonallmajorplatforms | |
Nextdecade:explosiveinterest??? | |
Scriptingsupportssoftwarereuse | |
ScriptingsimplifiesGUIprogramming | |
Scriptsarefastenoughontoday'scomputers | |
PythonsupportsbothshortscriptsandJava/C++-likesystems |
GUI:PythonvsC
Case:makeawindowonthescreenwiththetext'HelloWorld' | |
C+X11:176linesofuglycode | |
Python+Tk:6linesofreadablecode#!/usr/bin/envpython fromTkinterimport* root=Tk() Label(root,text='Hello,World!', foreground="white",background="black").pack()root.mainloop() | |
JavaandC++codesarelongerthanPython+Tk |
TherelationtoOOP
· | Object-orientedprogrammingcanalsobeusedtoparameterizetypes |
· | IntroducebaseclassAandarangeofsubclasses,allwitha(virtual)printfunction |
· | LetdebugworkwithvarasanAreference |
· | NowdebugworksforallsubclassesofA |
· | Advantage:completecontrolofthelegalvariabletypesthatdebugareallowedtoprint(maybeimportantinbigsystemstoensurethatafunctioncanallowmaketransactionswithcertainobjects) |
· | Disadvantage:muchmorework,muchmorecode,lessreuseofdebuginnewoccasions |
WhentouseC,C++,Java,Fortran
Doestheapplicationimplementcomplicatedalgorithmsanddatastructures? | |
Doestheapplicationmanipulatelargedatasetssothatexecutionspeediscritical? | |
Aretheapplication'sfunctionswell-definedandchangingslowly? | |
Willstrongtypingbeanadvantage,e.g.,inlargedevelopmentteams? |
Personalapplicationsofscripting
Automatemanualinteractionwiththecomputer | |
Customizeyourownworkingenvironmentandbecomemoreefficient | |
Havemorefun | |
Increasethereliabilityofyourwork (whatyoudidisdocumentedinthescript,visualizationscanbeautomaticallytaggedwithinputdata) | |
Scripts(usually)runonUnix,Windows,Macandmanyhand-helddevices(i.e.scriptsarecross-platform) | |
YougetthepowerofUnixalsoinnon-Unixenvironments |
Python'sadvantagesoverPerl
Pythoniseasiertolearnbecauseofitscleansyntaxandsimple/clearconcepts | |
PythonsupportsOOinamucheasierwaythanPerl | |
GUIprogramminginPythoniseasier (becauseoftheOOfeatures) | |
DocumentingPythoniseasierbecauseofdocstringsandmorereadablecode | |
ComplicateddatastructuresareeasiertoworkwithinPython | |
PythonissimplertointegratewithC++andFortran | |
PythoncanbeseamlesslyintegratedwithJava |
Perl'sadvantagesoverPython
Perlismorewidespread | |
Perlhasmoreadditionalmodules | |
Perlisfaster | |
Perlenablesmanydifferentsolutionstothesameproblem | |
Perlprogrammingismorefun(?)andmoreintellectuallychallenging(?) |
Perlisverythehigh-levelC?
NumericalPython(NumPy)
NumPyenablesefficientnumericalcomputinginPython | |
NumPyisaPython/Cpackagewhichoffersefficientarrays(contiguousstorage)andmathematicaloperationsinC | |
OldNumericmodule:fromNumericimport* | |
NewNumarraymodule:fromnumarrayimport*NumPycontainsothermodulesaswell |
Pythonandnumericalcomputing
Filla2DNumPyarraywithfunctionvalues:n=2000 a=zeros((n,n),Float) xcoor=arange(0,1,1/float(n)) ycoor=arange(0,1,1/float(n)) foriinrange(n): forjinrange(n):a[i,j]=f(xcoor,ycoor[j]) | |
Fortran/C/C++version:(normalized)time1.0 | |
Pythonversion:time75 | |
NumPyvectorizedevaluationoff:time3 |
Conclusions
Pythonloopsoverarraysareextremelyslow | |
NumPymaybesufficient | |
However,NumPyvectorizationmaybeinconvenient -plainloopsinFortran/C/C++aremucheasier! | |
WriteadministeringcodeinPython | |
Identifybottlenecks(viaprofiling) | |
MigrateslowPythoncodetoFortran,C,orC++ |
ThenatureofPythonvs.C
APythonvariablecanholddifferentobjects:d=3.2#dholdsafloat d='txt'#dholdsastringd=Button(frame,text='push')#instanceofclassButton | |
InC,C++andFortran,avariableisdeclaredofaspecifictype:doubled;d=4.2;d="somestring";/*illegal,compilererror*/ | |
ThisdifferencemakesitquitecomplicatedtocallC,C++orFortranfromPython |
CallingCfromPython
SupposewehaveaCfunctionexterndoublehw1(doubler1,doubler2); | |
WewanttocallthisfromPythonasfromhwimporthw1 r1=1.2;r2=-1.2s=hw1(r1,r2) | |
ThePythonvariablesr1andr2holdnumbers,weneedtoextracttheseintheCcode,converttodoublevariables,andthencallhw1 | |
Thisisdoneinwrappercode |
Wrappercode
BetweenPythonandhw1weneedwrappercode:staticPyObject*_wrap_hw1(PyObject*self,PyObject*args){ PyObject*resultobj; doublearg1; doublearg2; doubleresult; if(!PyArg_ParseTuple(args,(char*)"dd:hw1",&arg1,&arg2)){ returnNULL;/*wrongargumentsprovided*/ } result=(double)hw1(arg1,arg2); resultobj=PyFloat_FromDouble(result); returnresultobj; |
Python+Matlab=true
APythonmodule,pymat,enablescommunicationwithMatlab:fromNumericimport* importpymat x=arrayrange(0,4*math.pi,0.1) m=pymat.open() #cansendNumPyarraystoMatlab: pymat.put(m,'x',x); pymat.eval(m,'y=sin(x)') pymat.eval(m,'plot(x,y)') #getanewNumPyarrayback: y=pymat.get(m,'y') |
ComparisonwithMatlab
ThedemonstratedfunctionalitycanbecodedinMatlabaswell | |
WhyPython+F77? | |
Wecandefineourowninterfaceinamuchmorepowerfullanguage(Python)thanMatlab | |
WecanmuchmoreeasilytransferdatatoandfromorownF77orCorC++libraries | |
Wecanuseanyappropriatevisualizationtool | |
And,ofcourse,wecancallupMatlabifwewant | |
Python+F77givestailoredinterfacesandmaximumflexibility |
DisadvantagesofFortran77
Thebasicvariablestypesareprimitive | |
NostructorclassconstructinF77 | |
Nodynamicmemoryallocation | |
Veryprimitivelanguagefortextprocessing,listsandmorecomplicateddatastructures | |
F77codesaredifficulttoextend,maintainandre-use | |
F90/F95:extensionofF77withclasses (butnotvirtualfunctions,templatesetc.) | |
TheefficiencyofF90/F95isstillproblematic,andF77programmersmoveveryslowlytoF90/F95 |
AdvantagesofFortran77
F77isaverysimplelanguage | |
F77iseasytolearn | |
F77wasmadeforcomputingmathematicalformulasandoperatingefficientlyonplainarrays | |
F77isstill(andwillforeverbe?)thedominatinglanguagefornumericalcomputing | |
LotsofwelltestedandefficientF77librariesexist | |
Compilershave50yearsofexperiencewithoptimizingF77loopsoverarrays | |
Result:F77ishardtobeatwhenitcomestoarrayoperations |
Myopinion
UseF77fortime-criticalloops(arrayoperations) | |
MaketherestoftheprograminPython,C++,JavaorF95 | |
PythonandF77isaneasy-to-usepair! | |
Note:integrationofF77withC++orJavaisnotalwaysstraightforward |
AboutthisPage
[i]AprogrammercanbesignificantlymoreproductiveinPythonthaninJava.Howmuchmoreproductive?Themostwidelyacceptedestimateis5-10times.Onthebasisofmyownpersonalexperiencewiththetwolanguages,Iagreewiththisestimate.ManagerswhoareconsideringaddingPythontotheirorganization'slistofapproveddevelopmenttools,however,cannotaffordtoacceptsuchreportsuncritically.Theyneedevidence,andsomeunderstandingofwhyprogrammersaremakingsuchclaims.Thispageisforthosemanagers.Onthispage,Ipresentalistofside-by-sidecomparisonsoffeaturesofJavaandPython.Ifyoulookatthesecomparisons,youcanseewhyPythoncanbewrittenmuchmorequickly,andmaintainedmuchmoreeasily,thanJava.Thelistisnotlong--itismeanttoberepresentative,notexhaustive.Thispagelooksonlyatprogrammerproductivity,anddoesnotattempttocompareJavaandPythononanyotherbasis.Thereis,however,onerelatedtopicthatisvirtuallyimpossibletoavoid.PythonisaJavavs.PythonProductivity-anOverview
TherearethreemainlanguagecharacteristicsthatmakeprogrammersmoreproductivewithPythonthanwithJava.Java | Python |
staticallytypedInJava,allvariablenames(alongwiththeirtypes)mustbeexplicitlydeclared.Attemptingtoassignanobjectofthewrongtypetoavariablenametriggersatypeexception.That'swhatitmeanstosaythatJavaisastaticallytypedlanguage.Javacontainerobjects(e.g.VectorandArrayList)holdobjectsofthegenerictypeObject,butcannotholdprimitivessuchasint.TostoreanintinaVector,youmustfirstconverttheinttoanInteger.Whenyouretrieveanobjectfromacontainer,itdoesn'trememberitstype,andmustbeexplicitlycasttothedesiredtype. | dynamicallytypedInPython,youneverdeclareanything.Anassignmentstatementbindsanametoanobject,andtheobjectcanbeofanytype.Ifanameisassignedtoanobjectofonetype,itmaylaterbeassignedtoanobjectofadifferenttype.That'swhatitmeanstosaythatPythonisadynamicallytypedlanguage.Pythoncontainerobjects(e.g.listsanddictionaries)canholdobjectsofanytype,includingnumbersandlists.Whenyouretrieveanobjectfromacontainer,itremembersitstype,sonocastingisrequired.Formoreinformationonstaticvs.dynamictyping,see |
verbose"aboundinginwords;usingorcontainingmorewordsthanarenecessary" | concise(akaterse)"expressingmuchinafewwords.Impliesclean-cutbrevity,attainedbyexcisionofthesuperfluous" |
notcompact | compactInTheNewHacker'sDictionary,EricS.Raymondgivesthefollowingdefinitionfor"compact":Compactadj.Ofadesign,describesthevaluablepropertythatitcanallbeapprehendedatonceinone'shead.Thisgenerallymeansthethingcreatedfromthedesigncanbeusedwithgreaterfacilityandfewererrorsthananequivalenttoolthatisnotcompact. |
ThereasonforthisisthatJava,virtuallyaloneamongobject-orientedprogramminglanguages,usescheckedexceptions—exceptionsthatmustbecaughtorthrownbyeverymethodinwhichtheymightappear,orthecodewillfailtocompile.Recently(asofJune2003)thereseemstobeanincreasingamountofunhappinesswithJava'suseofcheckedexceptions.SeeBruceEckel's
Iliketheideaofcheckedexceptionsinsomesituations,butforcingeverymethodtodealwith(catchingorthrowing)allexceptionsthatitschildcallsormaycallcanbetedious.I'dratherbeabletoignoreanexceptionandletitpropagateupwards.Sometimes,I'drathernotworryaboutexceptionsatall.
Example
InExample
Java'sstring-handlingcapabilitiesaresurprisinglyweak.(ButtheyhaveimprovedconsiderablywiththeadditionofthesplitmethodtotheStringclassinJava1.4.)Example[/b]CodetoaddaninttoaVector,andthenretrieveit.Thisexampleillustratesboththeverbosityandnon-compactnessofJava,whencomparedtoPython.InJava,anewIntegerobjectmustbecreatedandinitializedfromtheintbeforeitcanbeaddedtotheVector.Inordertoretrievethevalue,thememberoftheVectormustbecastbacktoanInteger,andthenconvertedbacktoanint.InPython,noneoftheseconversionsarenecessary.Java | Python |
publicVectoraList=newVector; publicintaNumber=5; publicintanotherNumber; aList.addElement(newInteger(aNumber)); anotherNumber=((Integer)aList.getElement(0)).intValue(); | aList=[] aNumber=5 aList.append(aNumber) anotherNumber=aList[0] |
Inparticular,thisexampleillustratestheclumsinessofcontainerobjectsinJava,whichrequirecastinganobjectwheneveritisextractedfromacontainer.ItisacommonpracticeamongJavaprogrammerstoovercomethisclumsinessbywritingapplication-specificcontainerobjectstowrapJava'sgenericcontainers.Youmight,forexample,haveanEmployeesclasstowrapavectorofEmployeeobjects.Theget()methodoftheEmployeesobjectwouldretrievetheappropriatememberoftheVector,andcastitbacktoanEmployeeobjectbeforereturningit.ThisisactuallyagoodpracticeinJava.Butithastheeffectofincreasingthenumberofclassesintheapplication--classesthattheprogrammermustwrite--and(becauseeachJavaclassmustexistinitsownfile)itincreasesthenumberofJavafilesthattheprogrammermustmanage.Noneofthis,ofcourse,isnecessaryinPython.TheburdenonJavaprogrammerswillbeeasedsomewhatinJava1.5withtheintroductionof
Example
Verbosityisnotjustamatterofincreasingthenumberofcharactersthatmustbetyped--itisalsoamatterofincreasingthenumberofplaceswheremistakescanbemade.TheJavacodeonthelefthas5controlcharacters:(){};wherethecorrespondingPythoncodehasonlyonecontrolcharacter,thecolon.(Ortwo,ifyoucountindentation.Seebelow.)Java | Python |
if(a>b) { a=b; b=c; } | ifa>b: a=b b=c |
Omittingorduplicatingsuchcharactersiseasytodoaccidentally,andconstitutesasevereerrorinthecode.Inmypersonalestimate,Ispend5timesasmuchtimefixingsucherrorsinJavaasIdoinPython.Itreallycutsintoyourproductivity--andyourcreativeenergy--whenyouspendthatmuchofyourtimejusttryingtosatisfythecompiler.Technically,PythonhasanothercontrolcharacterthatJavadoesnota€”indentation.ButtherequirementforcorrectindentationisthesameinJavaasitisinPython,becauseinbothlanguagescorrectindentationisapracticalrequirementforhuman-readablecode.ThePythoninterpreterautomaticallyenforcescorrectindentation,whereastheJavacompilerdoesnot.WithJava,youneedanadd-onproductsuchasthe
Inastaticallytypedlanguage,everyvariablenameisboundboth(1)toatype(atcompiletime,bymeansofadatadeclaration)and(2)toanobject.Thebindingtoanobjectisoptional—ifanameisnotboundtoanobject,thenameissaidtobenull.Onceavariablenamehasbeenboundtoatype(thatis,declared)itcanbebound(viaanassignmentstatement)onlytoobjectsofthattype;itcannoteverbeboundtoanobjectofadifferenttype.Anattempttobindthenametoanobjectofthewrongtypewillraiseatypeexception. | Inadynamicallytypedlanguage,everyvariablenameis(unlessitisnull)boundonlytoanobject.Namesareboundtoobjectsatexecutiontimebymeansofassignmentstatements,anditispossibletobindanametoobjectsofdifferenttypesduringtheexecutionoftheprogram. |
employeeName=9 employeeName="SteveFerg" |
Pythonisadynamically-typedlanguage.Javaisastatically-typedlanguage.Inaweaklytypedlanguage,variablescanbeimplicitlycoercedtounrelatedtypes,whereasinastronglytypedlanguagetheycannot,andanexplicitconversionisrequired.(NotethatIsaidunrelatedtypes.Mostlanguageswillallowimplicitcoercionsbetweenrelatedtypesa€”forexample,theadditionofanintegerandafloat.ByunrelatedtypesImeanthingslikenumbersandstrings.)Inatypicalweaklytypedlanguage,thenumber9andthestring"9"areinterchangeable,andthefollowingsequenceofstatementsislegal.
a=9 b="9" c=concatenate(a,b)//produces"99" d=add(a,b)//produces18 |
Inastronglytypedlanguage,ontheotherhand,thelasttwostatementswouldraisetypeexceptions.Toavoidtheseexceptions,somekindofexplicittypeconversionwouldbenecessary,likethis.
a=9 b="9" c=concatenate(str(a),b) d=add(a,int(b)) |
BothJavaandPythonarestronglytypedlanguages.ExamplesofweaklytypedlanguagesarePerlandRexx.Athirddistinctionmaybemadebetweenmanifestlytypedlanguagesinwhichvariablenamesmusthaveexplicittypedeclarations,andimplictlytypedlanguagesinwhichthisisnotrequired.Moststaticlanguagesarealsomanifestlytyped(Javacertainlyis),but
fromthesite...(somefromanoldersite)Jythonisanimplementationofthehigh-level,dynamic,object-oriented
Interactiveexperimentation-JythonprovidesaninteractiveinterpreterthatcanbeusedtointeractwithJavapackagesorwithrunningJavaapplications.ThisallowsprogrammerstoexperimentanddebuganyJavasystemusingJython.
Rapidapplicationdevelopment-
Strengths:Abilitytouseascriptinglanguagefromwithinjava.Thisalonemakesitworthwhile!
ExcellentabilitytoinvokeJavaobjectsfromPythoncode.Thismeansthatyouhaveeasyaccesstoallthosejavalibraries.Infact,it'softenEASIERtocalljavaobjectsfromthePythonsidethanfromthejavaside!Theonlytimeitgetsannoyingiswhentherearemultiplemethodswiththesamenamebutmultiplesignatures.
PrettydarneasytoinvokePythonobjectsfromJavacode.Thislessused,butvitallyimportantforcompleteintegration.
Allthe"obvious"conversionsareperformedforyou.Strings,numbers,arrays,andthingslikethataretypicallyconvertedforyouwithlittleeffort.Ajava.lang.StringjustbecomesaPythonstring(andvice-versa)withnoneedto"convert".Withfancierobjectsyou'llneedtomakesomeeffort.
PythoninterpretercaneasilybeembeddedinJava.Theexistanceof"exec"(orit'sequivalent)in
Weaknesses:Classloadingisweak.Forexample,ifyouchangeascript,youeitherneedtorunitwithanewclassloaderorrestarttheapplicationthatwillexecthescript.Furthermore,reloadisshallow,soifanyimportedscriptschange,theyalsoneedtoberecompiledandrununderanewclassloader.
JythonprogramsrunmuchmoreslowlythanCPythonones.
JythonisaboutonetenthofaversionorsobehindCPython,plusitdoesn'thaveallthesamelibrariesandfunctionalityasCPython.
Javaarraysareaproblem.UsethejarraymoduleforJavaarraysupport.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WhatarethecriteriaIshouldconsiderwhendecidingbetweenNumericPython,MatlaborOctave?
Jan24th,200108:25[Note:Thisisacomplicatedquestion.Iamcurrentlytryingmakethisdeterminationformyself,too.ThisiswhatIcameupwithafterabitofsearchingandtrying.Hopefullymoreknowlegeablepeoplewilladdsomemeat.]
MathematicalFeatures:
-CurrentlyMatlabsetsthestandard.OctaveistrailingMatlabbyseveralversions.ThemaingistbehindOctaveistoprovideafreeimplementationofMatlab.
-Numpyhasasetofbasicfeaturesthatcovermostofwhatisrequiredforastandardundergraduatenumericalanalysiscurriculum,(standardnumericallinearalgebra,FFT)butnotmuchmore.Fancystufflikedomaintriangulationsisnotsupportedanddoesnotseemcurrentlyavailable.[Don'tknowOctave'sstatusonthisparticularissue.]
-Therearesomebindingstostandardnumericallibraries,e.g.Multipack[Linkhttp://oliphant.netpedia.netiscurrentlybroken]
GraphicalCapabilities:
-Again,Matlabisstateoftheart.
-AfrequentcriticismaboutOctaveisthatitsgraphicalcapabilitiesaresubstandard,inparticularwithregardstopublicationquality3Dgraphics.[Currentstatus?]
-Therearegraphicaladd-onsfornumpy[Noexperiencewithany.]
InterfacestoExternalCode:
-AllthreearesufficientlyabletointerfacewithexternalCorFortrancode.
ProgrammingLanguage:
-Numpybuildsuponattractivegeneral-purposeobject-orientedprogramminglangage.
-OctaveandMatlabsharemostlythesamespecialpurposelanguage.MaybesecondweakestpointofMatlabafterLicencing.
-SomeclumsynessinNumpywithMatrixmultiplication.Maydisappearatsomepoint,seehttp://python.sourceforge.net/peps/pep-0211.html http://python.sourceforge.net/peps/pep-0225.html
-ExistingPhythonmodulesshouldmakeiteasytointerfacewithInternetorlow-levelI/Oifsodesired.
Documentation:
-Matlab:Lotsofbooksandinternetresourcesavailable.
-Octave:SomeMathlabinfomaywork,somewhatcompleteusermanual,butsomewhatoutdated.
-Numpy:ManygoodbooksonPythoningeneral,arathershortbutup-to-dateintroductiontoNumpy.
Portability:
-NumpyandOctave;generallygood[Knownproblems?]
-Matlab:AnyplatformsthatMathworksseesfittosupport.Thiscurrentlyexcludesallnon-IntelLinuxports.
Lincense:
-Matlab:proprietary.
-Octave:GPL
-Numpy:PhythonLincense,isconsideredfree.
Conclusion:
IcurrentlyplantogiveNumpyatryasbothateachingplatformandfordoingsmalltoy-caseresearchcodes.Iamnotyetsurehowthiswillworkout,butIdecidedfortheprobablyleast-establishedoptionforthefollowingreasons.
-Afterfallingintotheproprietarytrapwithawell-knowprogramforsymbolicmath,Idonotwanttorepeatthisexperience.
-PythonasalanguageasanaesteticappealthatMatlab/Ocatvesimplydonothave.Further,thelanguageisusefulfarbeyondnumericalmath,whichisabigbonuswhenusingitasateachinglanguage.////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////PyMat-AninterfacebetweenPythonandMATLAB
Introduction
http://claymore.engineer.gvsu.edu/~steriana/Python
Functions
open([startcmd])ThisfunctionstartsaMATLABenginesessionandreturnsahandlethatisusedtoidentifythesessiontoallotherPyMatfunctions.Thehandleisofintegertype.OntheWin32platform,theoptionalparameter
startcmdisalwaysignored.OnUNIXplatforms,itindicatesthemethodofstartingMATLAB.Quotingfromthedocumentationforthe
engOpenfunctionfromtheMATLABAPIreferencemanual:OnUNIXsystems,if
startcmdisNULLortheemptystring,
engOpenstartsMATLABonthecurrenthostusingthecommand
matlab.If
startcmdisahost-name,
engOpenstartsMATLABonthedesignatedhostbyembeddingthespecifiedhostnamestringintothelargerstring:
"rshhostname/"/bin/csh-c'setenvDISPLAYhostname:0;matlab'/""If
startcmdisanyotherstring(haswhitespaceinit,ornonalphanumericcharacters),thestringisexecutedliterallytostartMATLAB.OnUNIXsystems,
engOpenperformsthefollowingsteps:1.Createstwopipes.2.ForksanewprocessandsetsupthepipestopassstdinandstdoutfromMATLAB(parent)totwofiledescriptorsintheengineprogram(child).3.ExecutesacommandtorunMATLAB(
rshforremoteexecution).UnderWindowsonaPC,
engOpenopensanActiveXchanneltoMATLAB.ThisstartstheMATLABthatwasregisteredduringinstallation.Ifyoudidnotregisterduringinstallation,onthecommandlineyoucanenterthecommand:
matlab/regserver
close(handle)ThisfunctionclosestheMATLABsessionrepresentedby
handle.
eval(handle,string)ThisfunctionevaluatesthegivenstringintheMATLABworkspace.Essentially,itisasifyouhadtypedthestringdirectlyinMATLAB'scommandwindow.Notethatthisfunctionalwayssucceedswithoutanyexceptionsunlessthehandleisinvalid,eveniftheevaluationfailedintheMATLABworkspace!.Youareresponsibleforverifyingsuccessfulexecutionofyourcode.
get(handle,name)ThisfunctionretrievesamatrixfromMATLAB'sworkspaceandreturnsaNumPyarraywiththesameshapeandcontents.The
nameparameterspecifiesthenameofthearrayinMATLAB'sworkspace.Currently,onlyone-dimensionalandtwo-dimensionalfloating-pointarrays(realorcomplex)aresupported.Structures,cellarrays,multi-dimensionalarrays,etc.arenotyetsupported.OnUNIXsystems,thisfunctioncanalsobeusedtoretrievecharacterstrings,inwhichcaseaPythonstringobjectisreturned.ThisfunctionalityisnotsupportedonWin32(duetoMATLABrestrictions).
put(handle,name,data)ThisfunctionplacesaPythonobjectintoMATLAB'sworkspaceunderthegivenname.The
dataparametercanbeoneofthreethings:ANumPyarray--inthiscase,anarrayofthesameshapeandcontentswillbeplacedintotheMATLABworkspace.TheMATLABarraywillbeindouble-precisionformat(realorcomplex),convertingfromtheNumPyarraytypeasnecessary.Onlyone-dimensionalortwo-dimensionalNumPyarraysaresupported.
APythonlistortuplecontainingnumericvalues.Inthiscase,aNumPyobjectiscreatedfromthelistortuple(asifyouwereusingNumPy's
array()function)andthatobjectisinstantiatedinMATLAB'sworkspace.
APythonstringobject.Inthiscase,aMATLABcharacterarraywillbeinstantiatedwiththecontentsofthestring.
Limitations
ThefollowinglimitationsapplytothecurrentversionofPyMat:Only1-Dand2-Ddouble-precision(realorcomplex)MATLABarraysaresupported(andsinglecharacterstrings).Matricesofhigherdimension,structurearrays,cellarrays,etc.arenotyetsupported.TheWin32platformdoesnotsupportretrievingcharacterstringsfromtheMATLABworkspace.
Examples
HereisasimpleexamplethatcomputestheDiscreteCosineTransformofashortNumPyarrayusingMATLAB'sdctfunction:
>>>importpymat
>>>fromNumericimport*
>>>x=array([1,2,3,4,5,6])
>>>H=pymat.open()
>>>pymat.put(H,'x',x)
>>>pymat.eval(H,'y=dct(x)')
>>>printpymat.get(H,'y')
[8.57321410e+00-4.16256180e+00-1.55403172e-15-4.08248290e-01-1.88808530e-15-8.00788912e-02]
>>>pymat.close(H)
Installation
Win32Simplyplacethe
pymat.pydfilesomewhereonyourPythonsearchpath.AlsoensurethatMATLAB's
BINdirectoryissomewhereonyourDOSpath,orelsethatyouhavecopiedMATLAB's
LIBENG.DLLand
LIBMX.DLLfilessomewhereonthispath.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Alightweightlanguagehasonedatastructureandusesitwell.Perl,TCL-StringPython,Scheme-ListMatlab-MatrixAllofthese(well,Idon'tactuallyknowTCLandPerl)offerotherdatatypes,butifyouusethepredominantdatatypethingsgomuchmoresmoothly.ThekeyisthatwhenthereisoneformofI/O,youcanhooklotsofthingstogethereasily.Aspointedoutattheconference,thistradesshorttermeaseofuseagainstlong-termmaintainability.
相关文章推荐
- java 获取文件或资源的路径小结
- JAVA学习小结(四)工厂模式区别
- java程序打包成JAR问题小结
- JAVA 集合类学习小结
- 流 JAVA IO 基本小结 通过一行常见的代码讨论:new BufferedReader(new InputStreamReader(System.in))
- Java String.indexOf() 函数用法小结
- JAVA中this用法小结
- Java,C#加密方法小结
- java异常—— finally 子句+带资源的 try语句
- Java队列很小的小结
- 解决Eclipse建立Maven项目后无法建立src/main/java资源文件夹的办法
- JAVA编程思想学习总结:第21章第3节共享受限资源
- java 线程同步 临时资源
- java中的I/O小结
- Android APK反编译得到Java源代码和资源文件
- JAVA学习笔记 -- 多线程之共享资源
- Java获取资源路径
- 关于如何在java的web应用获取服务器资源。
- maven 编译部署src/main/java下的资源文件
- Java中读取资源文件的工具类