"Amigo, sampung kubo!"

"Masaya akong matuto ng Java, Kapitan!"

"Kalmado, Amigo. Ngayon ay mayroon tayong isang napaka-kagiliw-giliw na paksa. Pag-uusapan natin kung paano nakikipag-ugnayan ang isang Java program sa mga panlabas na mapagkukunan at pag-aaralan natin ang isang napaka-kagiliw-giliw na pahayag ng Java. Mas mabuting huwag takpan ang iyong mga tainga."

"Nakikinig ako."

"Habang tumatakbo ang isang Java program, minsan ay nakikipag-ugnayan ito sa mga entity sa labas ng Java machine. Halimbawa, sa mga file sa disk. Ang mga entity na ito ay karaniwang tinatawag na external resources."

"Kung gayon, ano ang itinuturing na panloob na mapagkukunan?"

"Ang mga panloob na mapagkukunan ay ang mga bagay na nilikha sa loob ng Java machine. Karaniwan, ang pakikipag-ugnayan ay sumusunod sa pamamaraang ito:

Pahayag ng Try-with-resources

"Mahigpit na sinusubaybayan ng operating system ang mga mapagkukunang magagamit , at kinokontrol din ang nakabahaging pag-access sa mga ito mula sa iba't ibang mga program. Halimbawa, kung ang isang programa ay nagbabago ng isang file, kung gayon ang isa pang program ay hindi maaaring baguhin (o tanggalin) ang file na iyon. Ang prinsipyong ito ay hindi limitado sa mga file, ngunit nagbibigay sila ng pinaka madaling maunawaan na halimbawa.

"Ang operating system ay may mga function (API) na nagpapahintulot sa isang programa na kumuha at/o maglabas ng mga mapagkukunan. Kung ang isang mapagkukunan ay abala, kung gayon ang programa lamang na nakakuha nito ang maaaring gumana dito. Kung ang isang mapagkukunan ay libre, kung gayon ang anumang programa ay maaaring makakuha ng ito.

"Isipin mo na ang isang opisina ay nagbahagi ng mga coffee mug. Kung may kumuha ng mug, hindi na ito makukuha ng ibang tao. Pero kapag ang mug ay nagamit na, nalabhan, at naibalik sa pwesto nito, kahit sino ay maaaring kumuha muli."

"Got it. Ito ay tulad ng mga upuan sa subway o iba pang pampublikong sasakyan. Kung ang isang upuan ay libre, kung gayon ay maaaring kunin ito ng sinuman. Kung ang isang upuan ay occupied, kung gayon ito ay kontrolado ng taong kumuha nito."

"Tama. At ngayon pag-usapan natin ang pagkuha ng mga panlabas na mapagkukunan . Sa tuwing magsisimulang magtrabaho ang iyong Java program sa isang file sa disk, hihilingin ng Java machine ang operating system para sa eksklusibong pag-access dito. Kung ang mapagkukunan ay libre, ang Java machine ay makakakuha ng ito.

"Ngunit pagkatapos mong magtrabaho kasama ang file, ang mapagkukunang ito (file) ay dapat na ilabas, ibig sabihin, kailangan mong ipaalam sa operating system na hindi mo na ito kailangan. Kung hindi mo ito gagawin, ang mapagkukunan ay magpapatuloy na maging hawak ng iyong programa."

"Parang patas yan."

"Upang panatilihin ito sa ganoong paraan, ang operating system ay nagpapanatili ng isang listahan ng mga mapagkukunan na inookupahan ng bawat tumatakbong programa. Kung ang iyong programa ay lumampas sa itinalagang limitasyon ng mapagkukunan, ang operating system ay hindi na magbibigay sa iyo ng mga bagong mapagkukunan.

"Ito ay tulad ng mga programa na maaaring kainin ang lahat ng memorya..."

"May ganoong bagay. Ang magandang balita ay kung magwawakas ang iyong programa, ang lahat ng mga mapagkukunan ay awtomatikong inilabas (ang operating system mismo ang gumagawa nito)."

"Kung iyon ang magandang balita, ibig sabihin may masamang balita?"

"Talagang ganoon. Ang masamang balita ay kung nagsusulat ka ng isang server application..."

"Ngunit nagsusulat ba ako ng mga ganoong aplikasyon?"

"Maraming mga application ng server ang nakasulat sa Java, kaya malamang na isusulat mo ang mga ito para sa trabaho. Gaya ng sinasabi ko, kung nagsusulat ka ng isang server application, kung gayon ang iyong server ay kailangang tumakbo nang walang tigil sa mga araw, linggo, buwan, atbp."

"Sa madaling salita, ang programa ay hindi nagtatapos, at nangangahulugan iyon na ang memorya ay hindi awtomatikong inilabas."

"Eksakto. At kung magbubukas ka ng 100 file sa isang araw at hindi isasara ang mga ito, pagkatapos ng ilang linggo ay maaabot ng iyong application ang limitasyon ng mapagkukunan nito at mag-crash."

"Iyan ay kulang sa mga buwan ng matatag na trabaho! Ano ang maaaring gawin?"

"Ang mga klase na gumagamit ng mga panlabas na mapagkukunan ay may espesyal na paraan para sa pagpapalabas ng mga ito: close().

"Narito ang isang halimbawa ng isang programa na nagsusulat ng isang bagay sa isang file at pagkatapos ay isinasara ang file kapag ito ay tapos na, ibig sabihin, pinapalaya nito ang mga mapagkukunan ng operating system. Ito ay halos ganito:

Code Tandaan
String path = "c:\\projects\\log.txt";
FileOutputStream output = new FileOutputStream(path);
output.write(1);
output.close();
Ang landas sa file.
Kunin ang file object: kunin ang mapagkukunan.
Sumulat sa file
Isara ang file - bitawan ang mapagkukunan

"Ah... Kaya, pagkatapos magtrabaho sa isang file (o iba pang panlabas na mapagkukunan), kailangan kong tawagan ang close()pamamaraan sa bagay na naka-link sa panlabas na mapagkukunan."

"Oo. Mukhang simple ang lahat. Ngunit maaaring mangyari ang mga pagbubukod habang tumatakbo ang isang programa, at hindi ilalabas ang panlabas na mapagkukunan."

"At iyon ay napakasama. Ano ang gagawin?"

"Upang matiyak na ang close()pamamaraan ay palaging tinatawag, kailangan naming balutin ang aming code sa isang try- catch- finallyblock at idagdag ang close()paraan sa finallyblock. Magiging ganito ang hitsura nito:

try
{
   FileOutputStream output = new FileOutputStream(path);
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

"Hmm... May mali dito?"

"Tama. Ang code na ito ay hindi mag-compile, dahil ang outputvariable ay idineklara sa loob ng try{}block, at samakatuwid ay hindi makikita sa finallyblock.

Ayusin natin ito:

FileOutputStream output = new FileOutputStream(path);

try
{
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

"Okay na ba ang lahat ngayon?"

"Okay lang, ngunit hindi ito gagana kung may naganap na error kapag nilikha namin ang FileOutputStreambagay, at ito ay maaaring mangyari nang madali.

Ayusin natin ito:

FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
   output.close();
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   output.close();
}

"At gumagana ba ang lahat ngayon?"

"Mayroon pa ring ilang mga kritisismo. Una, kung may naganap na error sa paggawa ng FileOutputStreamobject, ang outputvariable ay magiging null. Ang posibilidad na ito ay dapat isaalang-alang sa finallyblock.

"Pangalawa, ang close()pamamaraan ay palaging tinatawag sa finallyblock, na nangangahulugang hindi ito kinakailangan sa tryblock. Ang huling code ay magiging ganito:

FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
}
catch (IOException e)
{
   e.printStackTrace();
}
finally
{
   if (output!=null)
      output.close();
}

"Kahit na hindi namin isaalang-alang ang catchbloke, na maaaring alisin, ang aming 3 linya ng code ay naging 10. Ngunit karaniwang binuksan namin ang file at nagsulat ng 1."

"Phew... Buti na lang natatapos ang usapin. Medyo naiintindihan, pero medyo nakakapagod, di ba?"

"Kaya nga. Kaya naman tinulungan kami ng mga tagalikha ng Java sa pamamagitan ng pagdaragdag ng ilang syntactic sugar. Ngayon ay lumipat tayo sa highlight ng programa, o sa halip, ang araling ito:

try-may-resources

"Simula sa ika-7 bersyon nito, ang Java ay may bagong try-with-resources na pahayag.

"Ito ay nilikha nang tumpak upang malutas ang problema sa ipinag-uutos na tawag sa close()pamamaraan."

"Mukhang may pag-asa!"

"Mukhang simple ang pangkalahatang kaso:

try (ClassName name = new ClassName())
{
   Code that works with the name variable
}

"Kaya ito ay isa pang pagkakaiba-iba ng try pahayag ?"

"Oo. Kailangan mong magdagdag ng mga panaklong pagkatapos ng trykeyword, at pagkatapos ay lumikha ng mga bagay na may mga panlabas na mapagkukunan sa loob ng mga panaklong. Para sa bawat bagay sa mga panaklong, ang compiler ay nagdaragdag ng isang finallyseksyon at isang tawag sa close()pamamaraan.

"Nasa ibaba ang dalawang katumbas na halimbawa:

Mahabang code Code na may try-with-resources
FileOutputStream output = null;

try
{
   output = new FileOutputStream(path);
   output.write(1);
}
finally
{
   if (output!=null)
   output.close();
}
try(FileOutputStream output = new FileOutputStream(path))
{
   output.write(1);
}

"Astig! Ang code na gumagamit ng try-with-resources ay mas maikli at mas madaling basahin. At mas kaunti ang code na mayroon tayo, mas maliit ang pagkakataong gumawa ng typo o iba pang error."

"Natutuwa akong nagustuhan mo ito. Siya nga pala, maaari nating idagdag catchat finallyi-block ang try-with-resources na pahayag. O hindi mo sila maidaragdag kung hindi kinakailangan.

Ilang mga variable sa parehong oras

"Maaaring madalas kang makatagpo ng isang sitwasyon kung kailan kailangan mong magbukas ng ilang mga file nang sabay-sabay. Sabihin nating kumukopya ka ng isang file, kaya kailangan mo ng dalawang bagay: ang file kung saan ka kumukopya ng data at ang file kung saan ka kumukopya ng data .

"Sa kasong ito, tryhinahayaan ka ng -with-resources na pahayag na lumikha ng isa ngunit ilang mga bagay dito. Ang code na lumilikha ng mga bagay ay dapat paghiwalayin ng mga semicolon. Narito ang pangkalahatang hitsura ng pahayag na ito:

try (ClassName name = new ClassName(); ClassName2 name2 = new ClassName2())
{
   Code that works with the name and name2 variables
}

Halimbawa ng pagkopya ng mga file:

Maikling code Mahabang code
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);

FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = input.readAllBytes();
   output.write(buffer);
}
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

FileInputStream input = null;
FileOutputStream output = null;

try
{
   input = new FileInputStream(src);
   output = new FileOutputStream(dest);

   byte[] buffer = input.readAllBytes();
   output.write(buffer);
}
finally
{
   if (input!=null)
      input.close();
   if (output!=null)
      output.close();
}

"Well, ano ang masasabi natin dito? try-with-resources is a wonderful thing!"

"Ang masasabi natin ay dapat nating gamitin ito."