यदि कोई अलग-अलग निर्देशिकाओं में एक ही केस-असंवेदनशील नाम के साथ दो सार्वजनिक जावा कक्षाएं लिखता है तो दोनों कक्षाएं रनटाइम पर उपयोग योग्य नहीं होती हैं। (मैंने विंडोज़, मैक और लिनक्स पर हॉटस्पॉट जेवीएम के कई संस्करणों के साथ इसका परीक्षण किया। मुझे आश्चर्य नहीं होगा अगर वहां अन्य जेवीएम हैं जहां वे एक साथ प्रयोग योग्य हैं।) उदाहरण के लिए, यदि मैं a
नामक एक वर्ग बनाता हूं और एक नाम A
:जावा क्लास नामों की केस संवेदनशीलता
// lowercase/src/testcase/a.java
package testcase;
public class a {
public static String myCase() {
return "lower";
}
}
// uppercase/src/testcase/A.java
package testcase;
public class A {
public static String myCase() {
return "upper";
}
}
तीन ग्रहण कोड युक्त परियोजनाओं ऊपर available from my website हैं।
अगर मैं ऐसा तरह दोनों वर्गों पर myCase
बुला की कोशिश:
System.out.println(A.myCase());
System.out.println(a.myCase());
typechecker सफल होता है, लेकिन जब मैं कक्षा फ़ाइल को चलाने के कोड सीधे ऊपर मैं द्वारा उत्पन्न:
Exception in thread "main" java.lang.NoClassDefFoundError: testcase/A (wrong name: testcase/a)
में जावा, नाम सामान्य मामले में संवेदनशील हैं। कुछ फाइल सिस्टम (जैसे विंडोज) केस असंवेदनशील हैं, इसलिए मुझे आश्चर्य नहीं है कि उपरोक्त व्यवहार होता है, लेकिन ऐसा लगता है कि गलत है। दुर्भाग्यवश जावा विनिर्देश अजीब रूप से गैर-महत्वपूर्ण हैं कि कौन से वर्ग दिखाई दे रहे हैं। Java Language Specification (JLS), Java SE 7 Edition (धारा 6.6.1, पेज 166) कहते हैं:
If a class or interface type is declared public, then it may be accessed by any code, provided that the compilation unit (§7.3) in which it is declared is observable.
धारा 7.3 में, JLS अत्यंत अस्पष्ट संदर्भ में एक संकलन इकाई के observability परिभाषित करता है:
All the compilation units of the predefined package java and its subpackages lang and io are always observable. For all other packages, the host system determines which compilation units are observable.
Java Virtual Machine Specification इसी तरह अस्पष्ट है (धारा 5.3.1):
The following steps are used to load and thereby create the nonarray class or interface C denoted by [binary name] N using the bootstrap class loader [...] Otherwise, the Java virtual machine passes the argument N to an invocation of a method on the bootstrap class loader to search for a purported representation of C in a platform-dependent manner.
यह सब महत्व के घटते क्रम में चार सवालों की ओर जाता है:
- क्या कोई गारंटी है कि प्रत्येक वर्ग में डिफ़ॉल्ट वर्ग लोडर (ओं) द्वारा कौन से वर्ग लोड किए जा सकते हैं? दूसरे शब्दों में, क्या मैं एक वैध, लेकिन खराब जेवीएम को कार्यान्वित कर सकता हूं, जो java.lang और java.io को छोड़कर किसी भी वर्ग को लोड नहीं करेगा?
- यदि कोई गारंटी है, तो ऊपर दिए गए उदाहरण में व्यवहार गारंटी का उल्लंघन करता है (यानी व्यवहार एक बग है)?
- क्या हॉटस्पॉट लोड
a
औरA
एक साथ बनाने का कोई तरीका है? एक कस्टम वर्ग लोडर काम लिखना होगा?
तो मुझे इस सीधे .. आप मिल गया है दो समान नाम वाले वर्गों 'testcase.a' मिलता है और' testcase.A ', आपके क्लासपाथ पर दो * अलग * निर्देशिकाओं में (क्योंकि आप उन्हें एक ही निर्देशिका में एक असंवेदनशील फाइल सिस्टम पर नहीं रख सकते हैं) - और आप सोच रहे हैं कि JVM को लोड करने के लिए सही वर्ग फ़ाइल क्यों नहीं मिल रही है? –
@GregHewgill आपने परिदृश्य को मेरे प्रश्न की शुरुआत में सही तरीके से वर्णित किया है, लेकिन मेरे प्रश्न अधिक व्यापक हैं। –
ठीक है, "क्लासपाथ" का पूरा विचार जेएलएस और जेवीएमएस के दृष्टिकोण से मंच-निर्भर है। उन दस्तावेज़ों में से कोई भी आपको इस प्रश्न को हल करने में मदद करेगा। –