2013-02-26 186 views
6

मैं यह निर्धारित करने की कोशिश कर रहा हूं कि मुझे अपनी बिल्ड श्रृंखला में कुछ जारों को फिर से कंपाइल करने की आवश्यकता है, अगर मेरे पास निम्नलिखित संरचना है, तो जार 1 संकलित करता है जब इसका 'स्रोत बदलता है और जब 2' इसके 'स्रोत में परिवर्तन होता है या जब जार 1 recompiled है।यदि कोई अभिभावक वर्ग/इंटरफ़ेस बदलता है तो कक्षा का बाइटकोड बदल सकता है?

जार 1:

public class Foo /* impl*/ 

जार 2:

public class Bar extends Foo /*impl*/ 

2 वर्गों के बीच अनुबंध मान लिया जाये कि यानी परिवर्तन नहीं करता है,। एक अमूर्त विधि जोड़ा जाता है या एक इंटरफ़ेस में एक विधि जोड़ा जाता है, आदि

क्या मुझे जार 2 को पुन: संकलित करने की आवश्यकता है? अर्थात। अगर फू के भीतर किसी निजी विधि में कुछ बदलाव किए जाते हैं तो बार को फिर से तैयार करने की आवश्यकता होगी?

मैंने एक में एक गुच्छा बदलने के बाद दो कक्षाओं के बाइटकोड की तुलना करके इसका परीक्षण करने की कोशिश की और उम्मीद की कि यह नहीं बदला। मेरे सहकर्मियों ने जोर देकर कहा कि उन्हें ऐसी परिस्थितियों का सामना करना पड़ा है जहां अनुबंध अपरिवर्तित था, फिर भी उन्हें काम करने के लिए सबकुछ फिर से जोड़ना पड़ा, हालांकि उन्हें याद नहीं आया कि कारण क्या था ... तो सबूत का बोझ मुझे दिखाने के लिए है यह जरूरी नहीं होना चाहिए। क्या कोई ऐसा मामला है जहां सुपरक्लस में बदलाव करने के लिए सबक्लास को फिर से सम्मिलित करने की आवश्यकता होगी, भले ही दोनों के बीच इंटरफ़ेस समान रहे?

उत्तर

6

मान लीजिए कि Foo चलो एक खुला स्रोत संगठन द्वारा जारी की है; और विभिन्न कंपनियों द्वारा लागू Foo के हजारों उप-वर्ग हैं।

अब कुछ बदलाव Foo पर किए गए हैं, और बाइनरी रूप में एक नया संस्करण जारी किया गया है, क्या सभी कंपनियां अपने कोड को दोबारा जोड़नी चाहिए? बिलकूल नही।(ठीक है, हम हर समय सभी कोड पुनः संयोजित करते हैं, लेकिन इसकी आवश्यकता नहीं है - Foo का नया जार किसी भी समस्या के बिना आसानी से गिराया जा सकता है)

यह बाइनरी संगतता का मुद्दा है, और आप जांच सकते हैं यह सुनिश्चित करने के लिए कि Foo में परिवर्तन सुरक्षित है। http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html

+0

लिंक के लिए धन्यवाद, मुझे लगता है कि मैं उम्मीद कर रहा था कि जब तक स्रोत नहीं बदला, तब तक क्लास फ़ाइल को बदलने की आवश्यकता नहीं होगी। ओह अच्छा। – Andrew

3

सामान्य स्थिति में आपको निर्भर वर्ग को फिर से सम्मिलित करना होगा। हालांकि अगर आपने Foo के किसी भी तरीके या फ़ील्ड को नहीं बदला है जो Bar द्वारा उपयोग किए जाते हैं तो Bar को Foo बदलते समय आपको पुन: संकलित करने की आवश्यकता नहीं है।

उदाहरण के लिए Foo विधि protected int foo()Bar से बुलाया था, लेकिन अगर आप इसे protected String foo() को हस्ताक्षर बदल गया है या private आप फिर से संकलन Bar करने के लिए उसकी दृश्यता बदल दिया है। इस मामले में Bar संकलित नहीं किया जा सकता है: आपको अपना कोड बदलना होगा।

लेकिन अगर Bar विधि foo() उपयोग नहीं करता है या यदि foo() का केवल कार्यान्वयन विवरण बदल रहे थे आप बिना फिर से संकलन Bar उपयोग कर सकते हैं।

+0

Foo में निरंतर मान को बदलने वाले बार को उपयोग करने के लिए भी एक पुन: संकलन की आवश्यकता होगी। – jtahlborn

+2

भी, जावा के पास [बाइनरी संगतता] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html) के लिए अच्छी तरह से परिभाषित नियम हैं। – jtahlborn

+0

@jtahlborn, नियमों के लिंक के लिए धन्यवाद। बहुत उपयोगी। – AlexR

2

निश्चित रूप से नहीं। आप ढांचे का उपयोग कर सकते हैं (जिसमें फू जैसे अनुबंध के साथ बहुत से वर्ग शामिल हैं) जो कि जार फ़ाइल में पैक किया गया है और आपको उन्हें स्रोत से संकलित करने की आवश्यकता नहीं है। लेकिन आपको पूरी तरह से यह सुनिश्चित करने की ज़रूरत है कि अप्रत्यक्ष रूप से अनुबंध सीधे नहीं बदला गया है। अप्रत्यक्ष परिवर्तन के कुछ उदाहरण के:

public class Foo { //v1 
    public static final int CONSTANT = 1;   
} 

public class Foo { //v2 
    public static final int CONSTANT = 2;   
} 

public class Bar extends Foo { 
    private int a(int value) { 
     switch (value) { 
      case CONSTANT: 
       return 1; 
     } 
     return 2; 
    } 
} 

आप वर्ग बार पुन: संयोजित नहीं है, तो यह अभी भी उपयोग करेगा मान 1

+0

क्या इसका मतलब यह है कि Bar.class फ़ाइल के अंदर 'कॉन्स्टेंट' int का मूल्य होगा? मेरा अंतर्ज्ञान कहता है कि इसे केवल 'फू/कॉन्स्टेंट' का रिफ्रेंस है और रनटाइम पर तदनुसार अपडेट किया जाएगा। कोई विचार क्यों यह मामला नहीं होगा? – Andrew

+0

यदि आप शायद हां से _switch_ से कुछ और उपयोग करेंगे। स्विच निर्देश को स्पष्ट संख्या की आवश्यकता होती है और रनटाइम में CONSTANT फ़ील्ड से मान पढ़ने के लिए संकलित करना संभव नहीं है। – ijrandom