JavaRush /جاوا بلاگ /Random-SD /جاوا ۾ خارجي قابل انٽرفيس

جاوا ۾ خارجي قابل انٽرفيس

گروپ ۾ شايع ٿيل
سلام! اڄ اسان جاوا شين کي سيريلائيز ۽ ڊيسيريلائيز ڪرڻ لاءِ پنهنجو تعارف جاري رکنداسين. آخري ليڪچر ۾، اسان کي متعارف ڪرايو ويو Serializable مارڪر انٽرفيس ، ان جي استعمال جا مثال ڏٺا، ۽ اهو پڻ سکيو ته ڪيئن ڪنٽرول ڪرڻ واري عمل کي ڪيئن ڪنٽرول ڪجي Transient keyword استعمال ڪندي . خير، "عمل کي منظم ڪريو،" يقينا، هڪ مضبوط لفظ آهي. اسان وٽ ھڪڙو لفظ آھي، ھڪڙو نسخو ID، ۽ اھو بنيادي طور تي آھي. باقي عمل جاوا اندر "هارڊ وائرڊ" آهي، ۽ ان تائين رسائي ناهي. هڪ سهولت جي نقطي نظر کان، اهو آهي، يقينا، سٺو. پر هڪ پروگرامر پنهنجي ڪم ۾ نه رڳو پنهنجي آرام تي ڌيان ڏيڻ گهرجي، صحيح؟ :) غور ڪرڻ لاء ٻيا عنصر آهن. تنهن ڪري، جاوا ۾ سيريلائيزيشن-ڊيسيريلائيزيشن جو واحد اوزار Serializable ناهي. اڄ اسان کي Externalizable انٽرفيس سان واقف ٿي ويندي . پر ان کان اڳ جو اسان ان جي مطالعي تي اڳتي وڌون، توھان وٽ ھڪڙو معقول سوال آھي: اسان کي ٻئي اوزار جي ضرورت ڇو آھي؟ Serializableمون پنهنجي نوڪري سان مقابلو ڪيو، ۽ سڄي عمل جي خودڪار عمل کي خوشيء سان نه ٿو ڪري سگهجي. مثال جيڪي اسان ڏٺا هئا اهي پيچيده نه هئا. سو معاملو ڇا آهي؟ بنيادي طور تي ساڳئي ڪم لاءِ ٻيو انٽرفيس ڇو؟ حقيقت اها آهي ته Serializableان جا ڪيترائي نقصان آهن. اچو ته انهن مان ڪجهه فهرست ڏيو:
  1. ڪارڪردگي. انٽرفيس Serializableڪيترائي فائدا آھن، پر اعلي ڪارڪردگي واضح طور تي انھن مان ھڪڙو نه آھي.

خارجي قابل انٽرفيس متعارف ڪرائڻ - 2

پهرين ، اندروني ميکانيزم Serializableپيدا ڪري ٿو وڏي مقدار ۾ خدمت جي معلومات ۽ مختلف قسم جي عارضي ڊيٽا آپريشن دوران.
ٻيو (توهان کي هاڻي ان ۾ وڃڻ جي ضرورت ناهي ۽ پنهنجي فرصت ۾ پڙهو جيڪڏهن توهان دلچسپي رکو ٿا)، ڪم Serializableتي ٻڌل آهي Reflection API استعمال ڪرڻ تي. هي تضاد توهان کي انهن شين کي ڪرڻ جي اجازت ڏئي ٿو جيڪا جاوا ۾ ناممڪن لڳي ٿي: مثال طور، خانگي شعبن جا قدر تبديل ڪريو. JavaRush وٽ Reflection API بابت هڪ بهترين مضمون آهي ، توهان ان بابت پڙهي سگهو ٿا هتي.

  1. لچڪدار. اسان سيريلائيزيشن-ڊيسيريلائيزيشن جي عمل کي ڪنٽرول نه ڪندا آهيون جڏهن استعمال ڪري رهيا آهيون Serializable.

    هڪ پاسي، اهو تمام آسان آهي، ڇاڪاڻ ته جيڪڏهن اسان ڪارڪردگي جي باري ۾ حقيقت ۾ پرواه نه ڪندا آهيون، ڪوڊ نه لکڻ جي صلاحيت آسان لڳي ٿي. پر ڇا جيڪڏهن اسان کي حقيقت ۾ سيريلائيزيشن منطق ۾ پنهنجون ڪجهه خاصيتون شامل ڪرڻ گهرجن (انهن مان هڪ جو مثال هيٺ ڏنو ويندو)؟

    لازمي طور تي، اسان سڀني کي ڪنٽرول ڪرڻ جي عمل کي transientڪجهه ڊيٽا کي خارج ڪرڻ لاء هڪ لفظ آهي، ۽ اهو ئي آهي. هڪ "ٽول کٽ" وانگر ترتيب ڏيو :/

  2. حفاظت. هي نقطو جزوي طور تي پوئين هڪ جي پٺيان آهي.

    اسان اڳ ۾ ان بابت گهڻو نه سوچيو آهي، پر ڇا جيڪڏهن توهان جي ڪلاس ۾ ڪجهه معلومات "ٻين ماڻهن جي ڪنن" (وڌيڪ واضح طور تي، اکين) لاء نه آهي؟ ھڪڙو سادو مثال آھي ھڪڙو پاسورڊ يا صارف جو ٻيو ذاتي ڊيٽا، جيڪو جديد دنيا ۾ قانون جي ھڪڙي گروپ پاران منظم ڪيو ويندو آھي.

    استعمال ڪندي Serializable، اسان اصل ۾ ان بابت ڪجھ به نٿا ڪري سگھون. اسان هر شي کي ترتيب ڏيو جيئن آهي.

    پر، سٺي طريقي سان، اسان کي لازمي طور تي ان قسم جي ڊيٽا کي انڪرپٽ ڪرڻ گهرجي ان کي فائل ۾ لکڻ يا ان کي نيٽ ورڪ تي منتقل ڪرڻ کان اڳ. پر Serializableاهو موقعو نه ڏيندو.

Externalizable Interface متعارف ڪرائڻ - 3خير، اچو ته آخرڪار ڏسون ته هڪ ڪلاس ڪيئن نظر ايندو Externalizable.
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class UserInfo implements Externalizable {

   private String firstName;
   private String lastName;
   private String superSecretInformation;

private static final long SERIAL_VERSION_UID = 1L;

   //...конструктор, геттеры, сеттеры, toString()...

   @Override
   public void writeExternal(ObjectOutput out) throws IOException {

   }

   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

   }
}
جئين توهان ڏسي سگهو ٿا، اسان اهم تبديليون ڪيون آهن! مکيه هڪ واضح آهي: جڏهن هڪ انٽرفيس کي لاڳو ڪرڻ، Externalizableتوهان کي لازمي طور تي ٻه لازمي طريقا لاڳو ڪرڻ گهرجن - writeExternal()۽ readExternal(). جيئن اسان اڳ ۾ چيو آهي، سيريلائيزيشن ۽ ڊيسيريلائيزيشن جي سموري ذميواري پروگرامر جي هوندي. بهرحال، هاڻي توهان هن عمل تي ڪنٽرول جي کوٽ جو مسئلو حل ڪري سگهو ٿا! سڄو عمل سڌو سنئون توهان جي طرفان پروگرام ڪيو ويو آهي، جيڪو، يقينا، هڪ وڌيڪ لچڪدار ميڪانيزم ٺاهي ٿو. ان کان علاوه، سيڪيورٽي جو مسئلو پڻ حل ڪيو ويو آهي. جئين توهان ڏسي سگهو ٿا، اسان وٽ اسان جي ڪلاس ۾ هڪ فيلڊ آهي: ذاتي ڊيٽا جيڪا محفوظ نه ٿي ڪري سگھجي غير انڪرپٽ. ھاڻي اسان آساني سان ڪوڊ لکي سگھون ٿا جيڪو ھن پابندي کي پورو ڪري. مثال طور، اسان جي ڪلاس ۾ ٻه سادي پرائيويٽ طريقا شامل ڪريو ڳجھي ڊيٽا کي انڪرپٽ ڪرڻ ۽ ڊريپ ڪرڻ لاءِ. اسان انهن کي فائل ۾ لکنداسين ۽ ان کي فائل مان انڪريپٽ فارم ۾ پڙهنداسين. ۽ اسان باقي ڊيٽا کي لکنداسين ۽ پڙهنداسين جيئن آهي :) نتيجي ۾، اسان جو ڪلاس ڪجهه هن طرح نظر ايندو:
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Base64;

public class UserInfo implements Externalizable {

   private String firstName;
   private String lastName;
   private String superSecretInformation;

   private static final long serialVersionUID = 1L;

   public UserInfo() {
   }

   public UserInfo(String firstName, String lastName, String superSecretInformation) {
       this.firstName = firstName;
       this.lastName = lastName;
       this.superSecretInformation = superSecretInformation;
   }

   @Override
   public void writeExternal(ObjectOutput out) throws IOException {
       out.writeObject(this.getFirstName());
       out.writeObject(this.getLastName());
       out.writeObject(this.encryptString(this.getSuperSecretInformation()));
   }

   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       firstName = (String) in.readObject();
       lastName = (String) in.readObject();
       superSecretInformation = this.decryptString((String) in.readObject());
   }

   private String encryptString(String data) {
       String encryptedData = Base64.getEncoder().encodeToString(data.getBytes());
       System.out.println(encryptedData);
       return encryptedData;
   }

   private String decryptString(String data) {
       String decrypted = new String(Base64.getDecoder().decode(data));
       System.out.println(decrypted);
       return decrypted;
   }

   public String getFirstName() {
       return firstName;
   }

   public String getLastName() {
       return lastName;
   }

   public String getSuperSecretInformation() {
       return superSecretInformation;
   }
}
اسان ٻن طريقن تي عمل ڪيو آهي جيڪي ساڳيا استعمال ڪن ٿا ObjectOutput out۽ پيٽرولر جي طور تي ObjectInputجيڪي اسان اڳ ۾ ئي ليڪچر ۾ سامهون آيا آهيون Serializable. صحيح وقت تي، اسان ضروري ڊيٽا کي انڪريپٽ يا ڊيڪرپٽ ڪندا آهيون، ۽ هن فارم ۾ اسان ان کي استعمال ڪندا آهيون اسان جي اعتراض کي ترتيب ڏيڻ لاء. اچو ته ڏسو ته اهو عمل ۾ ڪيئن نظر ايندو:
import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException, ClassNotFoundException {

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

       UserInfo userInfo = new UserInfo("Ivan", "Ivanov", "Ivan Ivanov's passport data");

       objectOutputStream.writeObject(userInfo);

       objectOutputStream.close();

   }
}
encryptString()۽ طريقن ۾ decryptString()، اسان خاص طور تي کنسول ۾ آئوٽ شامل ڪيو ته چيڪ ڪرڻ لاءِ ته ڳجهي ڊيٽا ڪهڙي شڪل ۾ لکي ۽ پڙهي ويندي. مٿي ڏنل ڪوڊ هيٺ ڏنل لائن کي ڪنسول ڏانهن ڪڍي ٿو: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh انڪريپشن ڪامياب ٿي وئي! فائل جو پورو مواد هن طرح نظر اچي ٿو: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx ھاڻي اچو ته استعمال ڪرڻ جي ڪوشش ڪريون Deserialization logic جيڪو اسان لکيو آھي.
public class Main {

   public static void main(String[] args) throws IOException, ClassNotFoundException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);


       UserInfo userInfo = (UserInfo) objectInputStream.readObject();
       System.out.println(userInfo);

       objectInputStream.close();

   }
}
خير، هتي ڪجھ به پيچيده نه لڳي، اهو ڪم ڪرڻ گهرجي! اچو ته هلون... Exception in theread "main" java.io.InvalidClassException: UserInfo; no valid constructor Externalizable Interface متعارف ڪرائڻ - 4 اڙي :( اهو ايترو سادو نه هو! ڊيسيريلائيزيشن ميڪانيزم هڪ استثنا ڏنو ۽ اسان کي هڪ ڊفالٽ ڪنسٽرڪٽر ٺاهڻ جي ضرورت هئي. مون کي تعجب آهي ڇو؟ Serializableاسان ان کان سواء منظم ڪيو ... :/ هتي اسان هڪ ٻي اهم nuance تي اچون ٿا وچ ۾ فرق Serializable۽ Externalizableڪوڙ نه رڳو پروگرامر لاءِ ”وڌايل“ پهچ ۽ پروسيس کي وڌيڪ لچڪدار طريقي سان منظم ڪرڻ جي صلاحيت ۾، پر ان ۾ پڻ . Serializableڪنهن شئي لاءِ مختص ڪئي وئي آهي، جنهن کان پوءِ اسٽريم مان ويلز پڙهيا ويندا آهن، جيڪي ان جي سڀني فيلڊن کي ڀريندا آهن، جيڪڏهن اسان استعمال ڪريون ٿا ته، Serializableاعتراض جي تعمير ڪندڙ کي نه سڏيو ويندو آهي! سمورو ڪم ريفريڪشن (Reflection API، جنهن جو اسان مختصر طور تي ذڪر ڪيو آهي) ذريعي ڪيو ويندو آهي. ليڪچر) جي صورت ۾، Externalizableڊيسيريلائيزيشن ميڪانيزم مختلف هوندو. شروع ۾، ڊفالٽ ڪنسٽرڪٽر سڏيو ويندو آهي، ۽ صرف ان کان پوء UserInfoٺاهيل اعتراض ميٿڊ تي سڏيو ويندو آهي readExternal()، جيڪو اعتراض جي فيلڊ کي ڀرڻ جو ذميوار آهي. ڇو ڪو به ڪلاس جيڪو انٽرفيس کي لاڳو ڪري ٿو ان Externalizableکي ڊفالٽ ڪنسٽرڪٽر هجڻ گهرجي . اچو ته ان کي پنهنجي ڪلاس ۾ شامل ڪريون UserInfo۽ ڪوڊ ٻيهر هلون:
import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException, ClassNotFoundException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);


       UserInfo userInfo = (UserInfo) objectInputStream.readObject();
       System.out.println(userInfo);

       objectInputStream.close();
   }
}
ڪنسول آئوٽ: Ivan Ivanov جي پاسپورٽ ڊيٽا UserInfo{firstName='Ivan', lastName='Ivanov', superSecretInformation='Ivan Ivanov جي پاسپورٽ ڊيٽا'} هڪ مڪمل طور تي مختلف معاملو! پهرين، ڳجهي ڊيٽا سان گڏ ڊسڪ ٿيل اسٽرنگ ڪنسول ڏانهن آئوٽ ڪيو ويو، ۽ پوء اسان جو اعتراض اسٽرنگ فارميٽ ۾ فائل مان هٿ ڪيو ويو! اهڙي طرح اسان ڪاميابيءَ سان سڀني مسئلن کي حل ڪيو :) سيريلائيزيشن ۽ ڊيسيريلائيزيشن جو موضوع سادو لڳي ٿو، پر جيئن توهان ڏسي سگهو ٿا، اسان جا ليڪچر ڊگها ٿي ويا. ۽ اهو سڀ ڪجهه ناهي! انهن مان هر هڪ انٽرفيس کي استعمال ڪرڻ وقت ڪيتريون ئي وڌيڪ ذلتون آهن، پر انهي ڪري ته هاڻي توهان جو دماغ نئين معلومات جي مقدار مان نه ڦٽو ڪري، آئون مختصر طور تي ڪجهه وڌيڪ اهم نقطا فهرست ڏيندس ۽ اضافي پڙهڻ لاء لنڪس مهيا ڪندس. پوء ڇا توهان کي ڄاڻڻ جي ضرورت آهي؟ پهرين ، جڏهن سيريلائيزنگ (اهو مسئلو ناهي ته توهان استعمال ڪريو Serializableيا Externalizable)، متغير ڏانهن ڌيان ڏيو static. جڏهن استعمال ڪيو وڃي، Serializableاهي شعبا بلڪل سيريل نه هوندا آهن (۽، مطابق، انهن جي قيمت تبديل نه ٿيندي آهي، ڇاڪاڻ ته staticشعبن جو تعلق طبقي سان آهي، نه اعتراض). پر جڏهن ان کي استعمال ڪندي، Externalizableتوهان پروسيس پاڻ کي سنڀاليو، تنهنڪري ٽيڪنيڪل طور تي اهو ٿي سگهي ٿو. پر ان جي سفارش نه ڪئي وئي آهي، ڇاڪاڻ ته هي نموني غلطين سان ڀريل آهي. ٻيو ، ڌيان متغير ڏانهن پڻ ادا ڪرڻ گهرجي موڊيفائر سان final. جڏهن استعمال ڪيو وڃي، Serializableاهي سيريلائيز ۽ ڊيسيريلائيز ڪيا وڃن ٿا، پر جڏهن استعمال ڪيو وڃي، اهو ناممڪن آهي ته هڪ متغير کي Externalizableختم ڪرڻfinal ناممڪن آهي ! سبب سادو آهي: سڀ finalفيلڊ شروع ڪيا ويندا آهن جڏهن ڊفالٽ تعمير ڪندڙ کي سڏيو ويندو آهي، ۽ ان کان پوء انهن جي قيمت تبديل نه ٿي ڪري سگهجي. تنهن ڪري، -فيلڊز تي مشتمل شين کي سيريل ڪرڻ لاءِ final، معياري سيريلائيزيشن ذريعي استعمال ڪريو Serializable. ٽيون ، جڏهن وراثت کي استعمال ڪيو وڃي، سڀني ورثي واري طبقن کي ڪجهه Externalizableطبقن مان نازل ٿيڻ گهرجي، انهن کي پڻ ڊفالٽ تعمير ڪندڙ هجڻ گهرجي. هتي سيريلائيزيشن ميڪانيزم بابت سٺا مضمونن جا ڪجهه لنڪ آهن: ملندا سين! :)
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION