دانستنی‌ها

۵ راه مختلف برای ساختن اشیا در جاوا

توسعه‌دهندگان جاوا معمولا هر روز تعداد زیادی شئ می‌سازند. شاید ما همیشه از سیستم‌های مدیریت وابستگی مثل Spring استفاده می‌کنیم تا این اشیا را بسازیم. اما راه‌های زیادی برای ساخت اشیا وجود دارند که در این مطلب به آن‌ها اشاره می‌کنیم.

۵ راه کلی برای ساخت اشیا در جاوا وجود دارد که با مثال توضیح می‌دهیم:

 constructor فراخوانی می‌شود  استفاده از کلمه کلیدی new
 constructor فراخوانی می‌شود  استفاده از تابع newInstance از کلاس Class
 constructor فراخوانی می‌شود  استفاده از تابع newInstance از کلاس Constructor
 بدون فراخوانی constructor  استفاده از تابع clone
 بدون فراخوانی constructor  استفاده از deserialization

اگر که برنامه‌ای که در پایان داده شده است را بررسی کنید، خواهید دید که توابع ۱،۲،۳ از constructor برای ساختن اشیا استفاده می‌کنند در حالیکه ۴،۵ بدون constructor اشیا را می‌سازند.

۱. استفاده از کلمه کلیدی new:

رایج‌ترین و معمول‌ترین راه برای ساختن اشیا و ساده‌ترین آن‌هاست. با استفاده از این روش می‌توانیم هر constructorای که می‌خواهیم را صدا بزنیم (بدون آرگومان یا با پارامتر)

Employee emp1 = new Employee();

 0: new           #19          // class org/programming/mitra/exercises/Employee  3: dup  4: invokespecial #21          // Method org/programming/mitra/exercises/Employee."":()V

۲. استفاده از تابع newInstance از کلاس Class

این متد constructor بدون آرگومان را فراخوانی می‌کند تا اشیا را بسازد.
ما می‌توانیم یک شی را با newInstance به این شکل بسازیم:

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance(); 

یا

Employee emp2 = Employee.class.newInstance();

51: invokevirtual    #70    // Method java/lang/Class.newInstance:()Ljava/lang/Object;

۳. استفاده از تابع newInstance از کلاس Constructor

مشابه تابع newInstance از کلاس Class، یک تابع newInstance در کلاس java.lang.reflect.Constructor وجود دارد که می‌توانیم برای ساخت اشیا از آن استفاده کنیم. به علاوه می‌توانیم یک constructor با پارامتر و یک private constructor هم با این روش فراخوانی کنیم.

Constructor<Employee> constructor = Employee.class.getConstructor(); Employee emp3 = constructor.newInstance();

111: invokevirtual  #80  // Method java/lang/reflect/Constructor.newInstance:([Ljava/lang/Object;)Ljava/lang/Object;

هر دوی این توابع newInstance به عنوان راه‌های بازتابی برای ساخت اشیا شناخته می‌شوند. در حقیقت این متد در کلاس Class از همین متد در کلاس Constructor استفاده می‌کند. به همین دلیل دومی ترجیح داده ‌می‌شود و در اغلب چارچوب‌ها مثل Spring، Hibernate، Struts و … مورد استفاده قرار می‌گیرد. برای اینکه تفاوت بین این دو متد را بهتر متوجه شوید این مطلب را بخوانید.

۴. از تابع clone استفاده کنید.

هروقت تابع clone را روی هر شئی صدا می‌زنیم، JVM دقیقا یک شی برای ما می‌سازد و تمام محتویات شئ قبلی را در آن کپی می‌کند. با این راه هیچ constructorای صدا نمی‌شود.
برای استفاده از متد clone روی شئ نیاز داریم اینترفیس Clonable را پیاده سازی کرده و متد clone را در آن تعریف کنیم:

Employee emp4 = (Employee) emp3.clone();

162: invokevirtual #87  // Method org/programming/mitra/exercises/Employee.clone ()Ljava/lang/Object;

۵. استفاده از deserialization

هر زمانی که شئی را serialize و deserialize می‌کنیم، JVM یک شي جدا برای ما می‌سازد. در deserialization، JVM از هیچ constuctorای برای ساخت اشیا استفاده نمی‌کند.
برای deserialize کردن یک شئ لازم است اینترفیس Serializable را در کلاسمان پیاده‌سازی کنیم:

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj")); Employee emp5 = (Employee) in.readObject();

 261: invokevirtual #118 // Method java/io/ObjectInputStream.readObject:()Ljava/lang/Object;

همانطور که در بایت کد بالا دیده می‌شود، همه چهار متد صدا زده شده و به invokevirtual که ساخت شئ مستقیم توسط این متدها مدیریت می‌شود تبدیل شده است. به جز در مورد اول که به دو فراخوانی تبدیل شده است. یکی از آن‌ها new و دیگری invokespecial است.

مثال:

کلاس کارمند را درنظر بگیرید:

class Employee implements Cloneable, Serializable {     private static final long serialVersionUID = 1L;     private String name;     public Employee() {         System.out.println("Employee Constructor Called...");     }     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + ((name == null) ? 0 : name.hashCode());         return result;     }     @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (getClass() != obj.getClass())             return false;         Employee other = (Employee) obj;         if (name == null) {             if (other.name != null)                 return false;         } else if (!name.equals(other.name))             return false;         return true;     }     @Override     public String toString() {         return "Employee [name=" + name + "]";     }     @Override     public Object clone() {         Object obj = null;         try {             obj = super.clone();         } catch (CloneNotSupportedException e) {             e.printStackTrace();         }         return obj;     } }

در برنامه‌جاوا زیر می‌خواهیم به پنج راه مختلف از این کلاس نمونه بسازیم. کد آن در گیت هاب هم در دسترس است:

ublic class ObjectCreation {     public static void main(String... args) throws Exception {         // By using new keyword         Employee emp1 = new Employee();         emp1.setName("Naresh");         System.out.println(emp1 + ", hashcode : " + emp1.hashCode());         // By using Class class's newInstance() method         Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")                                .newInstance();         // Or we can simply do this         // Employee emp2 = Employee.class.newInstance();         emp2.setName("Rishi");         System.out.println(emp2 + ", hashcode : " + emp2.hashCode());         // By using Constructor class's newInstance() method         Constructor<Employee> constructor = Employee.class.getConstructor();         Employee emp3 = constructor.newInstance();         emp3.setName("Yogesh");         System.out.println(emp3 + ", hashcode : " + emp3.hashCode());         // By using clone() method         Employee emp4 = (Employee) emp3.clone();         emp4.setName("Atul");         System.out.println(emp4 + ", hashcode : " + emp4.hashCode());         // By using Deserialization         // Serialization         ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));         out.writeObject(emp4);         out.close();         //Deserialization         ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));         Employee emp5 = (Employee) in.readObject();         in.close();         emp5.setName("Akash");         System.out.println(emp5 + ", hashcode : " + emp5.hashCode());     } }

این برنامه خروجی زیر را دارد:

Employee Constructor Called... Employee [name=Naresh], hashcode : -1968815046 Employee Constructor Called... Employee [name=Rishi], hashcode : 78970652 Employee Constructor Called... Employee [name=Yogesh], hashcode : -1641292792 Employee [name=Atul], hashcode : 2051657 Employee [name=Akash], hashcode : 63313419

منبع:

https://dzone.com/

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا