المتغير النهائي الثابت العام في فئة جافا المستوردة

StackOverflow https://stackoverflow.com/questions/1693091

سؤال

لقد صادفت عبر رمز جافا في مكان عملي. إليك السيناريو: هناك 2 فصول - ClassA و ClassB.

ClassA لا يوجد شيء ما عدا 4 قيم السلسلة الثابتة العامة في الداخل. والغرض منه هو استخدام هذه القيم مثل ClassA.variable (لا تسألني لماذا، ليس رمزي).

ClassB الواردات ClassA. وبعد لقد حررت قيم السلسلة في ClassA ورسمته. عندما هرب ClassB أستطيع أن أرى أنه يستخدم القيم القديمة - ليست القيم الجديدة. اضطررت إلى إعادة ترجمة ClassB لجعلها تستخدم قيم جديدة من ClassAفي (اضطررت إلى إعادة ترجمة الطبقات الأخرى التي تستورد ClassA!)

هل هذا فقط بسبب jdk 1.6 أو يجب أن أعرف سابقا لإعادة ترجمة ClassB أيضا! تنورني. :)

هل كانت مفيدة؟

المحلول

إذا كانت قيم final المتغيرات من الفصل ClassA يحدث أن تكون ثوابت تجميع الوقت، قد يكون المترجم قد شمله في الفصول باستخدام ClassA بدلا من إنشاء مرجع وقت التشغيل. أعتقد أن هذا ما حدث في حال وصفته.

مثال:

public class Flags {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

public class Consumer {
    public static void main(String[] args) {
         System.out.println(Flags.FOO);
    }
}

في هذا المثال، من المحتمل أن يتضمن المترجم قيمة FOO في التعليمات العامة ولدت Consumer بدلا من إنشاء مرجع وقت التشغيل المكافئ. إذا كانت قيمة FOO التغييرات في وقت لاحق، سيكون عليك إعادة الترجمة Consumer من أجل استخدام القيمة الجديدة.

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

int x = Flags.FOO * 10;

في هذا المثال، يتيح القيمة (هنا: 1) أن يلاحظ المحول البرمجي، أن الضرب لا فرق، ويمكن حذفه alltogether.

نصائح أخرى

إنها مشكلة التوافق الثنائية. يتم حل الإشارات إلى الحقول المستمرة في وقت الترجمة. السلوك الذي تراه هو الصحيح؛ إذا قمت بتغيير القيم في الفصل، فسيتعين عليك إعادة ترجمة العميل (فئة B). لتجنب مثل هذه المشاكل، فكر في إضافة ثوابت باستخدام نوع المعمنة، قدم في Java Release 5.0.

لماذا تحاول تجميع الفصول بشكل فردي؟

استخدم نظام الإنشاء مثل Maven أو Ant أو فقط دع IDE الخاص بك تفعل ذلك.

الشيء الآمن الوحيد الذي يجب القيام به هو إعادة ترجمة كل Java التي تعتمد على فئة Java التي تغيرت حتى يتم إعادة تجميع كل فئة يمكن إعادة تجميعها.

إذا كنت لا تستخدم القيم في رمز التبديل، فيمكنك القيام بذلك بدلا من ذلك:

public class A
{
    public static final int FOO;
    public static final String BAR;

    static
    {
        FOO = 42;
        BAR = "Hello, World!";
    }
}

ثم لم يعد التحويل البرمجي رمز صلب القيم في الفئات الأخرى التي تستخدمها.

افترض أن الفئة تبدو وكأنها هذه:

public class ClassA {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

إذا قمت بإعادة ترجمة ذلك، ستستمر ClassB في استخدام القيم القديمة. أعتقد أنه قد يعتمد على المحول البرمجي، لكنني أعتقد أن هذا هو السلوك النموذجي. إذا كنت لا ترغب في إعادة ترجمة Classb في كل مرة تتغير ثابتا في كلاسا، فسيتعين عليك فعل شيء مثل هذا:

public class ClassA {
    public static final int FOO = CONST(1);
    public static final int BAR = CONST(2);

    public static int CONST(int i) { return i; }
}

Becuase الآن Javac غير راغب في ضم الثوابت. بدلا من ذلك، سيتصل بطريقة const (int) عند تشغيل التهيئة الثابتة في كلاسا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top