JavaRush /Blog Java /Random-MS /Coffee break #88. Kuasa metadata: cara bekerja dengan kod...

Coffee break #88. Kuasa metadata: cara bekerja dengan kod spageti. Pengumpulan sampah di Jawa - cara ia berfungsi dan apakah kelebihannya

Diterbitkan dalam kumpulan

Kuasa metadata: cara bekerja dengan kod spageti

Sumber: Hackernoon Kita semua cuba menggunakan pendekatan biasa dan corak yang diketahui untuk mencipta aplikasi dengan usaha yang minimum dan impak maksimum. Kami mempunyai perpustakaan yang sangat baik dan rangka kerja yang berkuasa yang melaksanakan operasi rutin untuk kami. Kami menggunakan semua ini untuk menumpukan hanya pada logik perniagaan. Walau bagaimanapun, usaha ini sering membawa kita kepada kod spageti, terutamanya apabila ia berkaitan dengan melaksanakan fungsi tanpa penyelesaian sedia untuknya. Dalam artikel ini, saya ingin berkongsi dengan anda satu alat berkuasa yang, dalam pengalaman saya, tidak semua pembangun menghargai. Alat ini terdapat dalam kebanyakan bahasa pengaturcaraan, dan ia sangat kerap digunakan dalam banyak rangka kerja - anotasi. Coffee break #88.  Kuasa metadata: cara bekerja dengan kod spageti.  Pengumpulan sampah di Jawa - cara ia berfungsi dan apakah kelebihannya - 1

Adakah anda suka spageti?

Mari kita lihat contoh yang saya temui beberapa tahun lalu. Saya perlu menghuraikan hamparan Excel untuk meletakkan data yang dihuraikan ke dalam pangkalan data. Saya juga ingin mengumpul beberapa data daripada pangkalan data dan membuat hamparan. Untuk pelaksanaan, saya menggunakan perpustakaan Java yang terkenal - Apache POI. API perpustakaan menjadikan kerja anda lebih mudah kerana ia membolehkan anda membuat helaian, baris, sel dan elemen lain secara manual. Ini sangat bagus, tetapi apabila perlu menjana pelbagai hamparan Excel, kod tersebut menjadi tidak boleh dibaca sepenuhnya dan tidak boleh disokong. Akibatnya, seperti yang biasa berlaku, versi pertama aplikasi ternyata sangat mengerikan. Pelaksanaannya terdiri daripada kelas data yang mewakili rentetan dengan semua medan yang diperlukan untuk penghuraian. Terdapat juga penghurai di mana medan Excel dihuraikan sel demi sel dan diletakkan ke dalam contoh kelas data yang baru dibuat. Pada mulanya program ini berfungsi dengan baik dan melakukan apa yang diperlukan daripadanya. Masalah bermula apabila tiba masanya untuk membuat beberapa pengubahsuaian; kod itu tidak dibaca. Malah saya, yang menulis kod ini, tidak dapat mencari tempat yang sesuai untuk meletakkan baris baharu bagi melaksanakan fungsi baharu yang saya perlukan.

Menyelamat dalam anotasi

Menyimpan aplikasi daripada kod spageti anotasi ini. Untuk menyingkirkan kod yang tidak disokong, saya perlu mengalihkan logik untuk menentukan lajur yang hendak dihuraikan, jenis data yang terkandung dalam sel dan segala-galanya ke lokasi yang berbeza. Untuk melakukan ini, saya mencipta anotasi di mana saya menyatakan nama lajur untuk setiap medan kelas. Dalam anotasi, saya juga menambah pembolehubah yang membolehkan anda memilih warna dan fon sel. Oleh itu, kod dalam kelas parsing telah dikurangkan dengan ketara. Hanya satu pemproses mencipta hamparan secara dinamik berdasarkan parameter yang diambil daripada anotasi. Ia adalah satu kemenangan. Kemudian, untuk membuat sebarang perubahan pada aplikasi, saya hanya perlu mencipta kelas dengan anotasi. Penyelesaiannya mengingatkan perpustakaan Jackson, yang menghuraikan JSON menggunakan anotasi, dan saya rasa tidak perlu memberitahu betapa mudahnya Jackson atau perpustakaan yang serupa.
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnExcel {

    String name() default "";

    int position();

    ExcelColumnDataFormat cellTypePattern() default ExcelColumnDataFormat.NONE;

    IndexedColors cellColor() default IndexedColors.AUTOMATIC;

    ExcelTotalFormula total() default ExcelTotalFormula.NONE;

}
ColumnExcel columnExcel = field.getAnnotation(ColumnExcel.class);
Apabila aplikasi berkembang, ia menerima anotasi baharu yang boleh digunakan untuk mencipta sel dalam hamparan dengan fungsi di dalamnya. Pelbagai medan boleh didarab, ditolak dan sebarang fungsi Excel biasa boleh digunakan. Saya juga menambah jumlah baris untuk menunjukkan jumlah mengikut lajur. Dan saya melakukan semua ini hanya dengan mengubah sedikit parser utama dan hanya menambah anotasi pada kelas.
@ColumnExcel(
            name = "Views",
            position = 4,
            total = ExcelTotalFormula.SUM)
    private BigDecimal variableC;

    @ColumnExcelFormula(
            name = "Conversion",
            position = 5,
            cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
    )
    public String variableD(int rowNumber) {
        return new CellAddress(rowNumber, 4).formatAsString() + "*"
		+ new CellAddress(rowNumber, 2).formatAsString();
    }

    @ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
    public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
        return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
		+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
    }

Pengumpulan sampah di Jawa - cara ia berfungsi dan apakah kelebihannya

Sumber: Dev.to Pengumpulan sampah bermaksud memusnahkan atau membersihkan objek yang tidak digunakan dalam ingatan. Java mengendalikan deallocation memori secara automatik kerana apabila objek dicipta, ia menggunakan beberapa memori pada timbunan. Coffee break #88.  Kuasa metadata: cara bekerja dengan kod spageti.  Pengumpulan sampah di Jawa - cara ia berfungsi dan apakah kelebihannya - 2

Bagaimana ia berfungsi?

Sebelum Java, bahasa pengaturcaraan yang paling popular ialah C atau C++. Jika anda bercakap bahasa ini, maka anda harus tahu bahawa mereka menguruskan memori mereka sendiri secara manual. Sebagai contoh, C mempunyai kaedah seperti calloc() , malloc() dan realloc() yang akan membolehkan anda menggunakan memori penimbal. Anda mesti menentukan berapa banyak memori yang anda perlukan untuk program anda dan nyatakan apa yang dipanggil oleh API ini. Anda kemudiannya boleh mendapatkan penimbal memori untuk mencipta nod senarai terpaut atau sesuatu yang lain. Apabila program anda ditamatkan, pada satu ketika, anda juga bertanggungjawab untuk membersihkan memori itu. Jadi aplikasi besar yang ditulis dalam C terus memperuntukkan memori penimbal dan kadangkala terlupa untuk mengepamnya. Ini akhirnya menyebabkan kebocoran memori dan banyak masalah dalam aplikasi. Tidak seperti C dan C++, bahasa Java dilengkapi dengan pengurusan memori automatik melalui benang yang dipanggil pengumpul sampah. Tujuan utamanya adalah untuk membebaskan memori timbunan dengan memusnahkan objek yang tidak boleh diakses. Pengumpul sampah sentiasa berjalan di latar belakang.

Apakah objek yang tidak boleh diakses di Jawa?

Bilakah objek mendapat peluang untuk memulakan kutipan sampah? Jika terdapat objek yang tidak boleh diakses - objek yang tiada pautan aktif. Mari lihat contoh:
public static void main(String[] args)
{
// StringBuffer object sb is not eligible for garbage collection
StringBuffer sb = new StringBuffer("Flower Brackets");
System.out.println(sb);
// StringBuffer object sb is eligible for garbage collection
sb = null;
}
Dalam kaedah utama saya mencipta objek StringBuffer dan rujukan kepadanya. Pada ketika ini, objek StringBuffer tidak layak untuk pengumpulan sampah. Sekarang saya akan menetapkan objek StringBuffer kepada "null". Objek itu kini layak untuk pengumpulan sampah dan menjadi objek yang tidak boleh diakses dalam ingatan timbunan. Iaitu, pengumpulan sampah biasanya berfungsi dalam kes di mana objek menjadi tidak boleh diakses. Ini bermakna objek biasanya dicipta dalam konteks "jika blok" atau kaedah. Oleh itu, objek keluar dari skop sebaik sahaja pelaksanaan kaedah selesai dan boleh dilupuskan oleh pemungut sampah. Oleh kerana rujukan daripada objek lama kepada yang baharu wujud dalam bilangan yang terhad, ini bermakna objek yang telah lama wujud dalam aplikasi anda biasanya bukan objek yang baru dicipta. Berikut adalah beberapa istilah yang harus kita kenali; salah satunya ialah objek hidup. Ia adalah objek dalam aplikasi yang dirujuk oleh objek lain dalam aplikasi yang sama. Terdapat juga objek "mati". Objek mati ialah objek tidak boleh diakses yang dibuat semasa panggilan kaedah, dan setelah panggilan kaedah selesai, objek keluar dari konteks dan hanya duduk di atas timbunan.

Bilakah objek layak untuk kutipan sampah?

Jika objek tidak mempunyai sebarang pembolehubah rujukan, maka objek tersebut layak untuk pengumpulan sampah.

Bagaimana untuk menyediakan objek untuk pengumpulan sampah?

Di bawah adalah beberapa cara:
  1. null reference variable
    Student obj = new Student();
    obj = null;

  2. re-assign reference variable
    Student obj1 = new Student();
    Student obj2 = new Student();
    obj1 = obj2;

  3. reate anonymous object
    new Student();

    Sebaik sahaja objek disediakan kepada pemungut sampah, ia tidak segera dimusnahkan.

Apabila Mesin Maya Java menjalankan pemungut sampah, hanya objek itu dimusnahkan. NOTA: Pengumpul sampah hanya mengumpul objek yang dibuat menggunakan kata kunci "baru", untuk objek tanpa kata kunci "baru", gunakan kaedah finalize() . Terdapat beberapa kaedah untuk menjalankan pengumpul sampah dalam Mesin Maya Java:
  1. Kaedah System.gc().

  2. kaedah finalize().

  3. Kaedah Runtime.getRuntime().gc().

Kaedah gc() statik terletak dalam kelas Sistem . Kaedah ini meminta JVM memanggil pemungut sampah. Mari lihat cara aplikasi Java memanggil pengumpul sampah menggunakan kaedah gc() .
public class GarbageCollector
{
public static void main(String[] args)
{
Employee obj1 = new Employee();
Employee obj2 = new Employee();
obj1 = null;
obj2 = null;
System.gc();
}
public void finalize()
{
System.out.println("object garbage collected");
}
}
Keputusan:
objek sampah dikumpul objek sampah dikumpul
Kaedah finalize() dipanggil sebelum objek dibersihkan. Kaedah ini ditakrifkan dalam kelas Objek :
protected void finalize() throws Throwable
  1. Kaedah Finalize digunakan untuk menutup sambungan ke pangkalan data.

  2. Kaedah ini dipanggil oleh pemungut sampah, bukan JVM.

  3. Kita perlu mengatasi kaedah finalize() . Kerana ia mempunyai pelaksanaan yang kosong.

  4. Ia dipanggil sekali sahaja bagi setiap objek.

Kaedah getRuntime().gc() hadir dalam kelas runtime. Ia mengembalikan objek Runtime yang dikaitkan dengan aplikasi Java semasa. Mari lihat kaedah ini dalam program Java.
public class Demo
{
public static void main(String[] args)
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
// nullifying reference variable
obj1 = null;
// nullifying reference variable
obj2 = null;
// running Garbage Collector
Runtime.getRuntime().gc();
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Garbage collector called");
System.out.println("Object garbage collector: " + this);
}
}
Keputusan:
Pengumpul sampah dipanggil Pengumpul sampah Objek: Demo@2130772 Pengumpul sampah dipanggil Pengumpul sampah Objek: Demo@cd4e940

Faedah pengumpulan sampah:

  1. Pengumpulan sampah di Jawa berlaku secara automatik, yang menyelamatkan kita daripada beban tambahan untuk membebaskan memori terpakai. Ini menjadikan memori program Java lebih cekap.
  2. Pengumpulan sampah memastikan integriti program.
  3. Kami tidak perlu menulis sebarang kod tambahan kerana pengumpul sampah adalah sebahagian daripada JVM.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION