JavaRush /Java Blog /Random-TL /Coffee break #230. Ano ang Mga Tala sa Java at paano ito ...

Coffee break #230. Ano ang Mga Tala sa Java at paano ito gumagana?

Nai-publish sa grupo
Pinagmulan: JavaTechOnline Ang artikulong ito ay nagbibigay ng malalim na pagtingin sa konsepto ng Mga Tala sa Java na may mga halimbawa, kasama ang kanilang syntax, kung paano gawin ang mga ito, at kung paano gamitin ang mga ito. Coffee break #230.  Ano ang Mga Tala sa Java at paano gumagana ang mga ito - 1Ang mga rekord sa Java ay isa sa mga magagandang tampok na unang ipinakilala sa Java 14 bilang isang tampok na preview at sa wakas ay lumabas sa paglabas ng Java 17. Maraming mga developer ang aktibong gumagamit nito, na tumutulong sa kanila na matagumpay na mabawasan ang isang malaking halaga ng boilerplate code. Bukod dito, salamat sa mga tala, hindi mo kailangang magsulat ng isang linya ng code upang gawing hindi nababago ang isang klase.

Kailan gagamitin ang Record sa Java?

Kung gusto mong magpasa ng hindi nababagong data sa pagitan ng iba't ibang layer ng iyong application, ang paggamit ng Record ay maaaring maging isang magandang pagpipilian. Bilang default, ang Mga Tala sa Java ay hindi nababago, na nangangahulugan na hindi namin mababago ang kanilang mga pag-aari kapag nalikha na ang mga ito. Bilang resulta, nakakatulong ito sa amin na maiwasan ang mga error at mapabuti ang pagiging maaasahan ng code. Sa madaling salita, gamit ang Record sa Java, awtomatiko kaming makakabuo ng mga klase.

Saan ko magagamit ang Record sa Java?

Sa pangkalahatan, maaari kaming gumamit ng mga talaan sa anumang sitwasyon kung saan kailangan naming magdeklara ng mga simpleng lalagyan ng data na may mga hindi nababagong katangian at awtomatikong nabuong mga pamamaraan. Halimbawa, nasa ibaba ang ilang mga kaso ng paggamit kung saan maaaring maging kapaki-pakinabang ang mga talaan: Mga bagay sa paglilipat ng data (Data transfer objects (DTO): Magagamit namin ang Record upang magdeklara ng mga simpleng bagay sa paglilipat ng data na naglalaman ng data. Ito ay kapaki-pakinabang kapag naglilipat ng data sa pagitan ng iba't ibang layer ng application, tulad ng sa pagitan ng layer ng serbisyo at layer ng database. Configuration Objects : Maaaring gamitin ang record para magdeklara ng mga configuration object na naglalaman ng set ng configuration properties para sa isang application o module. Ang mga bagay na ito ay karaniwang may mga hindi nababagong katangian, na ginagawa itong ligtas sa thread at madaling gamitin. Mga bagay na may halaga. Maaaring gamitin ang record upang magdeklara ng mga value object na naglalaman ng set ng mga value na kumakatawan sa isang partikular na konsepto o modelo ng domain. Mga Tugon sa API : Kapag gumagawa ng REST API, karaniwang ibinabalik ang data sa anyo ng JSON o XML. Sa ganitong mga kaso, maaaring kailanganin mong tumukoy ng isang simpleng istraktura ng data na kumakatawan sa tugon ng API. Tamang-tama ang mga tala para dito dahil pinapayagan ka nitong tumukoy ng magaan at hindi nababagong istraktura ng data na madaling mai-serialize sa JSON o XML. Data ng pagsubok. Kapag nagsusulat ng mga unit test, madalas mong kailangang gumawa ng data ng pagsubok na kumakatawan sa isang partikular na senaryo. Sa ganitong mga kaso, maaaring kailanganin mong tumukoy ng isang simpleng istraktura ng data na kumakatawan sa data ng pagsubok. Ang mga talaan ay maaaring maging perpekto para dito dahil nagbibigay-daan ang mga ito sa amin na tumukoy ng magaan at hindi nababagong istraktura ng data na may kaunting boilerplate code. Mga bagay na tulad ng Tuple : Maaaring gamitin ang mga tala upang ideklara ang mga bagay na katulad ng Tuple na naglalaman ng nakapirming bilang ng mga nauugnay na halaga. Maaari itong maging kapaki-pakinabang kapag nagbabalik ng maraming halaga mula sa isang paraan o kapag nagtatrabaho sa mga koleksyon ng mga nauugnay na halaga.

Ano ang Record sa Java?

Ang record sa Java ay isang klase na idinisenyo upang mag-imbak ng data. Ito ay katulad ng isang tradisyonal na klase ng Java, ngunit mas magaan at may ilang natatanging tampok. Ang mga rekord ay hindi nababago bilang default, na nangangahulugan na ang kanilang estado ay hindi mababago kapag sila ay ginawa. Ginagawa nitong perpekto ang mga ito para sa pag-iimbak ng hindi nababagong data, tulad ng mga parameter ng pagsasaayos o mga halaga na ibinalik mula sa isang query sa database. Isa rin itong paraan para gumawa ng custom na uri ng data na binubuo ng isang hanay ng mga field o variable, pati na rin ang mga pamamaraan para sa pag-access at pagbabago sa mga field na iyon. Pinapadali ng record sa Java ang pagtatrabaho sa data sa pamamagitan ng pagbabawas ng dami ng boilerplate code na kailangang isulat nang paulit-ulit ng mga developer. Ang syntax para sa paglikha ng isang entry sa Java ay:
record Record_Name(Fields....)

Paano lumikha at gumamit ng Record sa Java na may mga halimbawa?

Tingnan natin kung paano gumawa at gumamit ng record sa Java sa programmatically.

Paggawa ng Record

Ang paggawa ng isang record sa programmatically ay hindi katulad ng paglikha ng isang regular na klase sa Java. Sa halip na klase ginagamit namin ang record na keyword . Kailangan mo ring magdeklara ng mga field na may mga uri ng data sa mga panaklong ng pangalan ng record. Narito ang isang halimbawa ng code na nagpapakita kung paano lumikha ng isang entry sa Java:
public record Book(String name, double price) { }
Sa halimbawang ito, gumawa kami ng record na tinatawag na Book na may dalawang field: pangalan at presyo . Ang pampublikong keyword ay nagpapahiwatig na ang entry na ito ay maaaring ma-access sa labas ng package kung saan ito ay tinukoy.

Gamit ang Record

Upang gumamit ng record sa Java, maaari naming i-instantiate ito gamit ang bagong keyword, tulad ng ginagawa namin sa isang regular na klase. Narito ang isang halimbawa:
Book book = new Book( "Core Java" , 324.25);
Narito ang isang bagong Book record instance ay nilikha na may name field na nakatakda sa Core Java at ang price field ay nakatakda sa 324.25 . Kapag nalikha na ang isang tala, maaaring ma-access ang mga field nito gamit ang pangalan ng field mismo. Walang mga get o set na pamamaraan. Sa halip, ang pangalan ng field ay nagiging pangalan ng pamamaraan.
String name = book.name();

double price = book.price();
Dito makikita natin ang halaga ng pangalan at mga patlang ng presyo na kinukuha mula sa talaan ng Aklat . Bilang karagdagan sa mga patlang, ang mga talaan ay mayroon ding ilang mga built-in na pamamaraan na maaari mong gamitin upang manipulahin ang mga ito. Halimbawa, toString() , equals() at hashCode() . Tandaan na ang mga tala ng Java ay hindi nababago bilang default, na nangangahulugang kapag nalikha na ang mga ito, hindi na mababago ang kanilang estado. Tingnan natin ang isa pang halimbawa kung paano lumikha at gumamit ng mga tala sa Java. Kunin natin ang isang kaso kung saan kailangan natin ng talaan upang mag-imbak ng impormasyon tungkol sa isang mag-aaral.
public record Student(String name, int age, String subject) {}
Lumilikha ito ng talaan na tinatawag na Student na may tatlong field: pangalan , edad at paksa . Maaari kaming lumikha ng isang halimbawa ng entry na ito tulad ng sumusunod:
Student student = new Student("John Smith", 20, "Computer Science");
Pagkatapos ay maaari nating makuha ang mga halaga ng field gamit ang pangalan ng field:
String name = student.name();
int age = student.age();
String subject= student.subject();

Ano ang hitsura ng Record pagkatapos ng compilation?

Dahil ang Record ay isang espesyal na uri lamang ng klase, kino-convert din ito ng compiler sa isang regular na klase, ngunit may ilang mga paghihigpit at pagkakaiba. Kapag nag-convert ang compiler ng record (Java file) sa bytecode pagkatapos ng proseso ng compilation, ang nabuong .class file ay naglalaman ng ilang karagdagang deklarasyon ng Record class . Halimbawa, sa ibaba ay ang bytecode na nabuo para sa entry ng Mag-aaral ng Java compiler:
record Student(String name, int age) {   }

Pagsusulat sa .class file (pagkatapos ng compilation)

Mahahanap din natin ang na-convert na klase sa ibaba kung gagamitin natin ang javap tool at ilalapat ang command sa ibaba mula sa command line. Mahalagang tandaan na kasama sa command line ng Java ang javap tool , na magagamit mo upang tingnan ang impormasyon tungkol sa mga field, constructor, at pamamaraan ng isang class file. >javap Konklusyon ng Mag-aaral: Kung susuriin natin nang mabuti ang bytecode, maaaring mayroon tayong ilang mga obserbasyon:
  • Pinalitan ng compiler ang Record keyword ng class .
  • Idineklara ng compiler ang class final . Ito ay nagpapahiwatig na ang klase na ito ay hindi maaaring pahabain. Nangangahulugan din ito na hindi ito maipapamana at likas na hindi nababago.
  • Ang na-convert na klase ay nagpapalawak ng java.lang.Record . Ipinapahiwatig nito na ang lahat ng mga tala ay isang subclass ng klase ng Record na tinukoy sa java.lang package .
  • Ang compiler ay nagdaragdag ng isang parameterized constructor.
  • Awtomatikong nabuo ng compiler ang toString() , hashCode() at equals() na mga pamamaraan .
  • Ang compiler ay nagdagdag ng mga pamamaraan para sa pag-access ng mga field. Bigyang-pansin ang paraan ng pagpapangalan ng convention - ang mga ito ay eksaktong kapareho ng mga pangalan ng field, hindi dapat magkaroon ng get o set bago ang mga pangalan ng field .

Mga field sa Records

Tinutukoy ng mga tala sa Java ang kanilang estado gamit ang isang hanay ng mga patlang, bawat isa ay may ibang pangalan at uri. Ang mga patlang ng isang tala ay ipinahayag sa header ng talaan. Halimbawa:
public record Person(String name, int age) {}
Ang entry na ito ay may dalawang field: pangalan ng uri String at edad ng uri int . Ang mga patlang ng isang tala ay ganap na pinal at hindi maaaring italagang muli pagkatapos malikha ang tala. Maaari kaming magdagdag ng bagong field, ngunit hindi ito inirerekomenda. Ang isang bagong field na idinagdag sa isang tala ay dapat na static. Halimbawa:
public record Person(String name, int age) {

   static String sex;
}

Mga Konstruktor sa Mga Tala

Tulad ng mga tradisyunal na constructor ng klase, ang mga record constructor ay ginagamit upang lumikha ng mga instance ng record. Ang mga tala ay may dalawang konsepto ng mga constructor: ang canonical constructor at ang compact constructor . Ang compact constructor ay nagbibigay ng isang mas maigsi na paraan upang simulan ang mga variable ng estado sa isang record, habang ang canonical constructor ay nagbibigay ng isang mas tradisyonal na paraan na may higit na flexibility.

Canonical constructor

Ang default na Java compiler ay nagbibigay sa amin ng isang all-argument constructor (all-field constructor) na nagtatalaga ng mga argumento nito sa mga kaukulang field. Ito ay kilala bilang canonical constructor. Maaari din kaming magdagdag ng lohika ng negosyo gaya ng mga conditional statement para ma-validate ang data. Nasa ibaba ang isang halimbawa:
public record Person(String name, int age) {

       public Person(String name, int age) {
           if (age < 18) {
              throw new IllegalArgumentException("You are not allowed to participate in general elections");
           }
      }
}

Compact na taga-disenyo

Binabalewala ng mga compact constructor ang lahat ng argumento, kabilang ang mga panaklong. Ang kaukulang mga patlang ay awtomatikong itinalaga. Halimbawa, ang sumusunod na code ay nagpapakita ng konsepto ng isang compact constructor sa Records :
public record Person(String name, int age) {

      public Person {
          if (age < 18) {
              throw new IllegalArgumentException("You are not allowed to participate in general elections");
          }
     }
}
Bilang karagdagan sa compact constructor, maaari mong tukuyin ang mga regular na konstruktor sa Record , tulad ng sa isang regular na klase. Gayunpaman, kailangan mong tiyakin na ang lahat ng mga konstruktor ay magsisimula sa lahat ng mga field ng record.

Mga Pamamaraan sa Mga Tala

Ang mga tala sa Java ay awtomatikong bumubuo ng isang hanay ng mga pamamaraan para sa bawat field sa talaan. Ang mga pamamaraang ito ay tinatawag na accessor method at may parehong pangalan sa field na nauugnay sa kanila. Halimbawa, kung ang isang record ay may field na pinangalanang price , awtomatiko itong magkakaroon ng method na tinatawag na price() na nagbabalik ng value ng price field . Bilang karagdagan sa mga awtomatikong nabuong pamamaraan ng accessor, maaari rin nating tukuyin ang sarili nating mga pamamaraan sa isang entry, tulad ng sa isang regular na klase. Halimbawa:
public record Person(String name, int age) {
   public void sayHello() {
      System.out.println("Hello, my name is " + name);
   }
}
Ang entry na ito ay may sayHello() na paraan na nagpi-print ng pagbati gamit ang name field .

Paano nakakatulong ang Record na bawasan ang boilerplate code

Tingnan natin ang isang simpleng halimbawa upang makita kung paano makakatulong ang mga notasyon ng Java na alisin ang boilerplate code. Sabihin nating mayroon kaming klase na tinatawag na Tao na kumakatawan sa isang taong may pangalan, edad at email address. Ito ay kung paano namin tinukoy ang isang klase sa tradisyonal na paraan. Code nang hindi gumagamit ng Record :
public class Person {

    private String name;
    private int age;
    private String email;

    public Person(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }

    public String getName() {

       return name;
    }

    public int getAge() {
       return age;
    }

    publicString getEmail() {
       return email;
    }

    public void setName(String name) {
       this.name = name;
    }

    public voidsetAge(int age) {
       this.age = age;
    }

    public void setEmail(String email) {
       this.email = email;
    }

    @Override
    public String toString() {
       return "Person{" +
         "name='" + name + '\'' +
         ", age=" + age +
         ", email='" + email + '\'' +
      '}';
    }
}
Tulad ng nakikita natin, ang klase na ito ay nangangailangan ng maraming boilerplate code upang tukuyin ang mga field, constructor, getter, setters, at toString() method . Bukod pa rito, ipagpalagay na gusto naming gawing hindi nababago ang klase na ito. Upang gawin ito, kailangan naming gumawa ng ilang karagdagang mga hakbang tulad ng:
  • Ideklara ang klase bilang pinal para hindi na ito mapalawig.
  • Ipahayag ang lahat ng mga patlang na pribado at pinal upang hindi sila mabago sa labas ng constructor.
  • Huwag magbigay ng anumang paraan ng setter para sa mga field.
  • Kung ang alinman sa mga patlang ay nababago, dapat mong ibalik ang isang kopya ng mga ito sa halip na ibalik ang orihinal na bagay.
Code gamit ang Record :
public record Person(String name, int age, String email) {}
Iyon lang! Sa isang linya lamang ng code, tinukoy namin ang isang klase na may parehong mga field, constructor, getter, setter, at toString() na pamamaraan bilang isang tradisyonal na klase. Ang Record syntax ang nangangalaga sa lahat ng boilerplate code para sa amin. Mula sa halimbawa sa itaas, malinaw na ang paggamit ng mga tala sa Java ay maaaring makatulong sa pagtanggal ng boilerplate code sa pamamagitan ng pagbibigay ng mas maigsi na syntax para sa pagtukoy ng mga klase na may nakapirming hanay ng mga field. Mas kaunting code ang kinakailangan upang tukuyin at gamitin ang mga talaan kaysa sa tradisyonal na diskarte, at ang mga talaan ay nagbibigay ng direktang access sa mga field gamit ang mga paraan upang i-update ang mga field. Ginagawa nitong mas nababasa, napanatili, at mas madaling kapitan ng error ang code. Bukod pa rito, gamit ang Record syntax , hindi namin kailangang gumawa ng anumang karagdagang bagay upang gawing hindi nababago ang klase. Bilang default, ang lahat ng mga field sa isang record ay pinal at ang klase ng record mismo ay hindi nababago. Samakatuwid, ang paglikha ng isang hindi nababagong klase gamit ang write syntax ay mas simple at nangangailangan ng mas kaunting code kaysa sa tradisyonal na diskarte. Sa mga talaan, hindi namin kailangang ideklara ang mga field bilang final , magbigay ng constructor na magpapasimula sa mga field, o magbigay ng mga getter para sa lahat ng field.

Karaniwang Record Classes

Maaari ding tukuyin ng Java ang mga generic na klase ng Records . Ang generic na entry class ay isang entry class na may isa o higit pang uri ng mga parameter. Narito ang isang halimbawa:
public record Pair<T, U>(T first, U second) {}
Sa halimbawang ito , ang Pair ay isang generic na klase ng record na kumukuha ng dalawang parameter ng uri T at U. Maaari tayong lumikha ng isang instance ng record na ito gaya ng sumusunod:
Pair<String, Integer>pair = new Pair<>( "Hello" , 123);

Nested na klase sa loob ng Record

Maaari mo ring tukuyin ang mga nested na klase at interface sa loob ng isang entry. Ito ay kapaki-pakinabang para sa pagpapangkat ng mga nauugnay na klase at interface, at maaaring makatulong na mapabuti ang organisasyon at pagpapanatili ng iyong codebase. Narito ang isang halimbawa ng isang entry na naglalaman ng isang nested class:
public record Person(String name, int age, Contact contact){

    public static class Contact {

       private final String email;
       private final String phone;

       public Contact(String email, String phone){
           this.email = email;
           this.phone = phone;
       }

       public String getEmail(){
          return email;
       }

       public String getPhone(){
          return phone;
       }
    }
}
Sa halimbawang ito, ang Tao ay isang entry na naglalaman ng nested Contact class . Sa turn, ang Contact ay isang static na nested class na naglalaman ng dalawang pribadong final field: email address at telepono. Mayroon din itong constructor na tumatanggap ng email at numero ng telepono, at dalawang paraan ng getter: getEmail() at getPhone() . Maaari kaming lumikha ng isang halimbawa ng Tao tulad nito:
Person person = new Person("John",30, new Person.Contact("john@example.com", "123-456-7890"));
Sa halimbawang ito, gumawa kami ng bagong Person object na pinangalanang John , edad 30, at isang bagong Contact object na may email john@example.com at telepono 123-456-7890 .

Nested interface sa loob ng Record

Narito ang isang halimbawang entry na naglalaman ng nested interface:
public record Book(String title, String author, Edition edition){
    public interface Edition{
       String getName();
   }
}
Sa halimbawang ito, ang Book ay ang entry na naglalaman ng nested na interface ng Edition . Sa turn, ang Edition ay isang interface na tumutukoy sa isang paraan ng getName() . Maaari kaming lumikha ng isang halimbawa ng Aklat tulad ng sumusunod:
Book book = new Book("The Hitchhiker's Guide to the Galaxy", "Douglas Adams", new Book.Edition() {

   public String getName() {

      return "Science Fiction";
   }
});
Sa halimbawang ito, lumikha kami ng bagong bagay sa Aklat na may pamagat na The Hitchhiker's Guide to the Galaxy ni Douglas Adams at isang bagong anonymous na pagpapatupad ng interface ng Edition na nagbabalik ng pangalang Science Fiction kapag tinawag ang getName() na paraan .

Ano pa ang magagawa ng Records?

  • Maaaring tukuyin ng mga entry ang mga custom na konstruktor. Sinusuportahan ng mga talaan ang mga parameterized na constructor, na maaaring tumawag sa isang default na constructor na may ibinigay na mga parameter sa kanilang mga katawan. Bilang karagdagan, sinusuportahan din ng mga talaan ang mga compact constructor, na katulad ng mga default na constructor ngunit maaaring magsama ng karagdagang functionality gaya ng mga pagsusuri sa katawan ng constructor.
  • Tulad ng anumang iba pang klase sa Java, maaaring tukuyin at gamitin ng Record ang mga pamamaraan ng halimbawa. Nangangahulugan ito na maaari kaming lumikha at tumawag ng mga pamamaraan na partikular sa klase ng pag-record.
  • Sa Record , hindi pinapayagan ang pagtukoy sa mga variable ng instance bilang mga miyembro ng klase dahil maaari lamang itong tukuyin bilang mga parameter ng constructor. Gayunpaman, sinusuportahan ng mga talaan ang mga static na field at static na pamamaraan, na maaaring magamit upang mag-imbak at mag-access ng data na karaniwan sa lahat ng mga pagkakataon ng klase ng record.

Maaari bang ipatupad ng isang rekord ang mga interface?

Oo, ang pagsusulat sa Java ay maaaring magpatupad ng mga interface. Halimbawa, ang code sa ibaba ay nagpapakita ng konsepto:
public interface Printable {
   void print();
}
public record Person(String name, int age) implements Printable {
   public void print() {
      System.out.println("Name: " + name + ", Age: " + age);
   }
}
Dito ay tinukoy namin ang isang napi-print na interface na may iisang print() na paraan . Tinukoy din namin ang isang entry na Tao na nagpapatupad ng Napi-print na interface . Ang talaan ng Tao ay may dalawang field: pangalan at edad , at nilalampasan ang paraan ng pag-print ng Nai-print na interface upang i-print ang mga halaga ng mga field na ito. Maaari naming i-instantiate ang isang entry ng Tao at tawagan ang paraan ng pag-print nito tulad nito:
Person person = new Person("John", 30);
person.print();
Ilalabas nito ang Pangalan: John, Edad: 30 sa console . Tulad ng ipinapakita sa halimbawa, ang mga tala ng Java ay maaaring magpatupad ng mga interface tulad ng mga regular na klase. Maaari itong maging kapaki-pakinabang para sa pagdaragdag ng gawi sa isang entry o para sa pagtiyak na ang isang entry ay sumusunod sa isang kontrata na tinukoy ng isang interface.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION