जब एक उच्च समवर्ती एकल वर्ग के लिए इकाई परीक्षणों के साथ मैं निम्नलिखित अजीब व्यवहार पर ठोकर खाई (JDK 1.8.0_162 पर परीक्षण):
private static class SingletonClass {
static final SingletonClass INSTANCE = new SingletonClass(0);
final int value;
static SingletonClass getInstance() {
return INSTANCE;
}
SingletonClass(int value) {
this.value = value;
}
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
System.out.println(SingletonClass.getInstance().value); // 0
// Change the instance to a new one with value 1
setSingletonInstance(new SingletonClass(1));
System.out.println(SingletonClass.getInstance().value); // 1
// Call getInstance() enough times to trigger JIT optimizations
for(int i=0;i<100_000;++i){
SingletonClass.getInstance();
}
System.out.println(SingletonClass.getInstance().value); // 1
setSingletonInstance(new SingletonClass(2));
System.out.println(SingletonClass.INSTANCE.value); // 2
System.out.println(SingletonClass.getInstance().value); // 1 (2 expected)
}
private static void setSingletonInstance(SingletonClass newInstance) throws NoSuchFieldException, IllegalAccessException {
// Get the INSTANCE field and make it accessible
Field field = SingletonClass.class.getDeclaredField("INSTANCE");
field.setAccessible(true);
// Remove the final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
// Set new value
field.set(null, newInstance);
}
मुख्य () विधि की अंतिम 2 पंक्तियाँ INSTANCE के मूल्य पर असहमत हैं - मेरा अनुमान है कि JIT ने विधि से पूरी तरह छुटकारा पा लिया क्योंकि क्षेत्र स्थिर अंतिम है। अंतिम कीवर्ड को हटाने से कोड आउटपुट सही मान बन जाता है।
सिंगल के लिए अपनी सहानुभूति (या इसके अभाव) को छोड़कर एक मिनट के लिए भूल जाते हैं कि इस तरह प्रतिबिंब का उपयोग करना मुसीबत के लिए पूछ रहा है - क्या मेरी धारणा सही है कि जेआईटी अनुकूलन को दोष देना है? यदि हां - तो क्या वे केवल स्थैतिक अंतिम क्षेत्रों तक सीमित हैं?
static final
क्षेत्र के साथ एक वर्ग है । इसके अलावा, इससे कोई फर्क नहीं पड़ता कि यह प्रतिबिंब हैक JIT या संगामिति के कारण टूटता है या नहीं।