مقدمة - لماذا تحتوي Java على حقول مؤقتة؟




مقدمة في الجافا (9)

لماذا تحتوي Java على حقول مؤقتة ؟


إنها ضرورية عندما لا ترغب في مشاركة بعض البيانات الحساسة التي تترافق مع التسلسل.


التسلسل هو عملية حفظ حالات الكائن بتنسيق دائم (مثل تدفق الملف أو قاعدة البيانات) ، واستعادته لاحقًا من الدفق (إزالة التسلسل). في Java ، يكون عنصر الفئة قابل للتسلسل إذا قام الفصل بتنفيذ واجهة java.io.Serializable. هذه هي واجهة علامة تشير إلى JVM أن الفئة مؤهلة للتسلسل.

public class User implements Serializable {

    private static final long serialVersionUID = 1234L;

    private String username;
    private String email;
    private transient String password;
    private Date birthday;
    private int age;

    public User(String username, String email, String password, Date birthday,
            int age) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.birthday = birthday;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("username: " + username);
        System.out.println("email: " + email);
        System.out.println("password: " + password);
        System.out.println("birthday: " + birthday);
        System.out.println("age: " + age);
    }

    // getters and setters

}

توجد ثلاث نقاط مهمة في فئة النموذج هذه: يجب أن تقوم بتنفيذ واجهة Serializable. وإلا ، فسنحصل على java.io.NotSerializableException عند محاولة تسلسل كائن من الصف. يتم تعريف ثابت باسم serialVersionUID وتعيين قيمة طويلة:

private static final long serialVersionUID = 1234L;

هذا ثابت تقليدي يجب أن يتم التصريح به عندما تقوم فئة بتنفيذ واجهة Serializable. يضمن الإصدار التسلسلي UID بشدة التوافق بين الإصدارات المتسلسلة وغير المتسلسلة للكائنات من الفئة ، وذلك لأن عملية التسلسل وإلغاء التسلسل يمكن أن تحدث على أجهزة كمبيوتر وأنظمة مختلفة. على الرغم من أن هذا التعريف اختياري ، فمن المستحسن دائمًا الإعلان عن serialVersionUID لفئة قابلة للتسلسل.

لاحظ أن حقل كلمة المرور تم وضع علامة عليه كعنصر مؤقت:

private transient String password;

لأننا لا نريد تخزين كلمة المرور عند إجراء تسلسل للعنصر. القاعدة هي ، عندما يتم وضع علامة على متغير كعبر ، لن يكون تسلسلها الكائن أثناء التسلسل.

المتغير المؤقت هو متغير قد لا يكون متسلسلًا. يمكنك استخدام الكلمة الأساسية العابرة للإشارة إلى جهاز Java الظاهري أن المتغير المشار إليه ليس جزءًا من الحالة المستمرة للكائن.

تعد مدخلات الوصول التي يدعمها Java ثابتة ، نهائية ، مجردة ، متزامنة ، أصلية ، متقلبة ، عابرة و strictfp.

يعطي الجدول التالي قائمة محددات الوصول والمعدلات Java التي يمكن تطبيقها على المتغيرات والطرق والفئات.

SPECIFIER/MODIFIER  LOCAL VARIABLE  INSTANCEVARIABLE    METHOD   CLASS
public              NA              A                   A         A
protected           NA              A                   A         NA
default             A               A                   A         A
private             NA              A                   A         NA
final               A               A                   A         A
static              NA              A                   A         NA
synchronized        NA              NA                  A         NA
native              NA              NA                  A         NA
volatile            NA              A                   NA        NA
transient           NA              A                   NA        NA
strictfp            NA              NA                  A         A

ببساطة ، الكلمة الرئيسية java العابرة تحمي الحقول من Serialize كأجزاء عداد غير عابرة.

في هذا التعليمة البرمجية الخاصة بنا فئة تجريدية BaseJob تقوم بتنفيذ واجهة Serializable ، نمتد من BaseJob لكننا لا نحتاج إلى إجراء تسلسل لمصادر البيانات المحلية والبعيدة ؛ التسلسل فقط organizationName و isSynced الحقول.

public abstract class BaseJob implements Serializable{
   public void ShouldRetryRun(){}
}

public class SyncOrganizationJob extends BaseJob {

   public String organizationName;
   public Boolean isSynced

   @Inject transient RemoteDataSource remoteDataSource;
   @Inject transient LocalDaoSource localDataSource;

   public SyncOrganizationJob(String organizationName) {
     super(new 
         Params(BACKGROUND).groupBy(GROUP).requireNetwork().persist());

      this.organizationName = organizationName;
      this.isSynced=isSynced;

   }
}

قبل أن أرد على هذا السؤال ، يجب أن أشرح لك SERIALIZATION ، لأنه إذا فهمت ما الذي يعنيه التسلسل في الكمبيوتر العلمية ، يمكنك بسهولة فهم هذه الكلمة.

التسلسل عندما يتم نقل كائن عبر الشبكة / المحفوظة على الوسائط الفعلية (ملف ، ...) ، يجب أن يكون الكائن "مسلسلاً". التسلسل يحول سلسلة كائن حالة البايت. يتم إرسال هذه البايتات على الشبكة / المحفوظة ويتم إعادة إنشاء الكائن من هذه البايتات.
مثال

public class Foo implements Serializable 
{
 private String attr1;
 private String attr2;
 ...
}

الآن إذا كنت تريد أن تفعل لا TRANSFERT / SAVED حقل من هذا الكائن SO ، يمكنك استخدام كلمة transient

private transient attr2;

Example


لأنه ليس كل المتغيرات ذات طبيعة قابلة للتسلسل


للسماح لك بتحديد المتغيرات التي لا تريد إجراء تسلسل لها.

في كائن قد يكون لديك معلومات لا تريد إجراء تسلسل / استمرارية (ربما إشارة إلى كائن مصنع الأصل) ، أو ربما ليس من المنطقي إجراء تسلسل. يعني وضع علامة على هذه "عابر" أن آلية التسلسل ستتجاهل هذه الحقول.


وفقًا لمعنى google عابر == دائمًا لفترة قصيرة ؛ غير دائمة.

الآن إذا أردت جعل أي شيء عابر في جافا ، استخدم كلمة مرور عابرة.

س: أين يمكن استخدام عابر؟

ج: بشكل عام في جافا ، يمكننا حفظ البيانات إلى الملفات عن طريق الحصول عليها في المتغيرات وكتابة تلك المتغيرات إلى الملفات ، وتعرف هذه العملية باسم التسلسل. الآن إذا أردنا تجنب البيانات المتغيرة ليتم كتابتها إلى ملف ، فسنجعل ذلك المتغير عابرًا.

نتيجة int عابرة = 10 ؛

ملاحظة: لا يمكن أن تكون المتغيرات المؤقتة محلية.


يتم استخدام transient للإشارة إلى أن حقل فئة لا يحتاج إلى تسلسل. ربما أفضل مثال هو حقل مؤشر Thread . لا يوجد عادةً أي سبب لإجراء تسلسل لسلسلة الرسائل ، لأن حالتها محددة للغاية.


يتم استخدام الكلمة الأساسية transient في Java للإشارة إلى أنه لا يجب إجراء تسلسل للحقل.

من Java Language Specification، Java SE 7 Edition ، Section 8.3.1.3. حقول transient :

قد يتم وضع علامة على المتغيرات transient لتشير إلى أنها ليست جزءًا من الحالة المستمرة لكائن ما.

على سبيل المثال ، قد يكون لديك حقول مشتقة من حقول أخرى ، ويجب أن يتم تنفيذها برمجيًا ، بدلاً من استمرار الحالة عبر التسلسل.

في ما يلي فئة GalleryImage التي تحتوي على صورة وصورة مصغرة مشتقة من الصورة:

class GalleryImage implements Serializable
{
    private Image image;
    private transient Image thumbnailImage;

    private void generateThumbnail()
    {
        // Generate thumbnail.
    }

    private void readObject(ObjectInputStream inputStream)
            throws IOException, ClassNotFoundException
    {
        inputStream.defaultReadObject();
        generateThumbnail();
    }    
}

في هذا المثال ، thumbnailImage هي صورة مصغرة يتم تكوينها باستدعاء طريقة generateThumbnail .

يتم تمييز الحقل imageImage transient ، لذلك يتم فقط تسلسل image الأصلية بدلاً من الاستمرار في كل من الصورة الأصلية والصورة المصغرة. وهذا يعني أن هناك حاجة إلى تخزين أقل لحفظ الكائن المتسلسل. (بالطبع ، هذا قد يكون أو لا يكون مرغوبا فيه تبعا لمتطلبات النظام - وهذا مجرد مثال).

في وقت إلغاء التسلسل ، يتم استدعاء الأسلوب readObject لتنفيذ أي عمليات ضرورية لاستعادة حالة الكائن مرة أخرى إلى الحالة التي حدث فيها عملية التسلسل. هنا ، يجب إنشاء الصورة المصغرة ، بحيث يتم تجاوز طريقة readObject بحيث يتم إنشاء الصورة المصغرة عن طريق استدعاء طريقة generateThumbnail .

للحصول على معلومات إضافية ، تحتوي المقالة " اكتشاف أسرار" لواجهة برمجة تطبيقات واجهة برمجة تطبيقات جافا (التي كانت متوفرة أصلاً على شبكة Sun Developer Network) على قسم يناقش استخدام سيناريو حيث يتم استخدام الكلمة الرئيسية transient لمنع تسلسل بعض الحقول.





transient