जवाबों:
कभी-कभी जावा जेनेरिक बस आपको वह नहीं करने देता जो आप करना चाहते हैं, और आपको कंपाइलर को प्रभावी ढंग से बताने की जरूरत है कि आप जो कर रहे हैं, वह वास्तव में निष्पादन के समय कानूनी होगा ।
जब मैं एक सामान्य इंटरफ़ेस का मजाक उड़ा रहा होता हूं, तो मुझे आमतौर पर यह दर्द होता है, लेकिन अन्य उदाहरण भी हैं। यह आमतौर पर चेतावनी से बचने के बजाय उसे दबा का एक तरीका बाहर काम करने की कोशिश कर रहा लायक है ( जावा जेनेरिक्स पूछे जाने वाले प्रश्न यहाँ मदद करता है), लेकिन कभी कभी भी यह करता है, तो है संभव है, यह इतना है कि चेतावनी को दबा neater है आकार के बाहर कोड झुकता है। हमेशा उस मामले में एक व्याख्यात्मक टिप्पणी जोड़ें!
इस विषय पर एक ही जेनेरिक एफएक्यू में कई खंड हैं, जो "अनियंत्रित" चेतावनी के साथ शुरू होता है? - यह अच्छी तरह से पढ़ने लायक है।
(YourClazz<?>)
- जावा कभी भी ऐसी जातियों के बारे में चेतावनी नहीं देता है क्योंकि वे सुरक्षित हैं। हालांकि यह हमेशा काम नहीं करेगा (विवरण के लिए सामान्य प्रश्न देखें)।
यह अनियंत्रित जेनेरिक संचालन (अपवाद नहीं) के बारे में संकलित चेतावनियों को दबाने के लिए एक टिप्पणी है, जैसे कि जातियां। यह अनिवार्य रूप से तात्पर्य है कि प्रोग्रामर को इन के बारे में सूचित करने की इच्छा नहीं थी, जिसे वह पहले से ही जानते हैं कि किसी विशेष बिट कोड का संकलन करते समय।
आप इस विशिष्ट एनोटेशन पर और अधिक पढ़ सकते हैं:
इसके अतिरिक्त, ओरेकल यहां एनोटेशन के उपयोग पर कुछ ट्यूटोरियल प्रलेखन प्रदान करता है:
जैसा कि उन्होंने इसे रखा,
"'अनियंत्रित' चेतावनी तब हो सकती है जब जेनेरिक के आगमन से पहले लिखी गई विरासत कोड के साथ इंटरफेस किया जाए (जेनरिक शीर्षक वाले पाठ में चर्चा की गई)।"
इसका मतलब यह भी हो सकता है कि वर्तमान जावा प्रकार सिस्टम संस्करण आपके मामले के लिए पर्याप्त नहीं है। इसे ठीक करने के लिए कई जेएसआर प्रस्ताव / हैक थे : टाइप टोकन, सुपर टाइप टोकन , क्लास.कास्ट ()।
यदि आपको वास्तव में इस सुप्रेशन की आवश्यकता है, तो इसे जितना संभव हो सके संकीर्ण करें (जैसे कि इसे कक्षा में या लंबी विधि पर न डालें)। एक उदाहरण:
public List<String> getALegacyListReversed() {
@SuppressWarnings("unchecked") List<String> list =
(List<String>)legacyLibrary.getStringList();
Collections.reverse(list);
return list;
}
SuppressWarning एनोटेशन एनोटेट तत्व के लिए दबाने संकलक चेतावनी किया जाता है। विशेष रूप से, unchecked
श्रेणी अनियंत्रित प्रकार के कलाकारों के परिणामस्वरूप उत्पन्न संकलक चेतावनियों के दमन की अनुमति देती है।
बस: यह एक चेतावनी है जिसके द्वारा कंपाइलर इंगित करता है कि यह प्रकार की सुरक्षा सुनिश्चित नहीं कर सकता है।
उदाहरण के लिए JPA सेवा विधि:
@SuppressWarnings("unchecked")
public List<User> findAllUsers(){
Query query = entitymanager.createQuery("SELECT u FROM User u");
return (List<User>)query.getResultList();
}
अगर मैं यहाँ @SuppressWarnings ("अनियंत्रित") को एनोटेट नहीं करता, तो उसे लाइन में समस्या होती, जहाँ मैं अपना रिजल्ट वापस करना चाहता हूँ।
शॉर्टकट टाइप-सेफ्टी में इसका मतलब है: एक प्रोग्राम को टाइप-सेफ माना जाता है अगर वह बिना किसी त्रुटि और चेतावनी के संकलित करता है और रनटाइम के दौरान कोई अप्रत्याशित क्लासकैस्टैसेप्शन नहीं बढ़ाता है।
मैं http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html पर निर्माण कर रहा हूं
जावा में, जेनेरिक को प्रकार के क्षरण द्वारा कार्यान्वित किया जाता है। उदाहरण के लिए, निम्न कोड।
List<String> hello = List.of("a", "b");
String example = hello.get(0);
के लिए संकलित है।
List hello = List.of("a", "b");
String example = (String) hello.get(0);
और List.of
के रूप में परिभाषित किया गया है।
static <E> List<E> of(E e1, E e2);
जो कि प्रकार के क्षरण के बाद बन जाता है।
static List of(Object e1, Object e2);
कंपाइलर को इस बात का कोई अंदाजा नहीं है कि रनटाइम के समय जेनेरिक प्रकार क्या हैं, इसलिए यदि आप ऐसा कुछ लिखते हैं।
Object list = List.of("a", "b");
List<Integer> actualList = (List<Integer>) list;
जावा वर्चुअल मशीन को पता नहीं है कि प्रोग्राम चलाते समय जेनेरिक प्रकार क्या हैं, इसलिए यह संकलन और चलता है, जैसा कि जावा वर्चुअल मशीन के लिए, यह List
टाइप करने के लिए एक कास्ट है (यह केवल एक चीज है जिसे यह सत्यापित कर सकता है, इसलिए यह केवल उसी को सत्यापित करता है)।
लेकिन अब इस लाइन को जोड़ दें।
Integer hello = actualList.get(0);
और जेवीएम एक अप्रत्याशित फेंक देगा ClassCastException
, क्योंकि जावा संकलक ने एक निहित डाली डाली।
java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer
एक unchecked
चेतावनी एक प्रोग्रामर को बताती है कि एक कलाकार एक कार्यक्रम को कहीं और अपवाद फेंकने का कारण बन सकता है। @SuppressWarnings("unchecked")
संकलक के साथ चेतावनी को दबाने से प्रोग्रामर का मानना है कि कोड सुरक्षित है और अप्रत्याशित अपवादों का कारण नहीं होगा।
आप ऐसा क्यों करना चाहते हो? जावा प्रकार प्रणाली सभी संभव प्रकार के उपयोग पैटर्न का प्रतिनिधित्व करने के लिए पर्याप्त नहीं है। कभी-कभी आप जान सकते हैं कि एक कास्ट सुरक्षित है, लेकिन जावा ऐसा कहने का एक तरीका प्रदान नहीं करता है - इस तरह की चेतावनी को छिपाने के लिए, @SupressWarnings("unchecked")
इसका उपयोग किया जा सकता है, ताकि एक प्रोग्रामर वास्तविक चेतावनियों पर ध्यान केंद्रित कर सके। उदाहरण के लिए, Optional.empty()
किसी एकल विकल्प को आवंटित करने से बचने के लिए एक सिंगलटन लौटाता है जो एक मूल्य को संग्रहीत नहीं करता है।
private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
यह कास्ट सुरक्षित है, क्योंकि एक खाली वैकल्पिक में संग्रहीत मूल्य को पुनर्प्राप्त नहीं किया जा सकता है, इसलिए अप्रत्याशित क्लास कास्ट अपवादों का कोई जोखिम नहीं है।
आप कंपाइलर चेतावनियों को दबा सकते हैं और जेनरिक को बता सकते हैं कि आपने जो कोड लिखा था, वह उसके अनुसार कानूनी है।
उदाहरण:
@SuppressWarnings("unchecked")
public List<ReservationMealPlan> retreiveMealPlan() {
List<ReservationMealPlan> list=new ArrayList<ReservationMealPlan>();
TestMenuService testMenuService=new TestMenuService(em, this.selectedInstance);
list = testMenuService.getMeal(reservationMealPlan);
return list;
}
एक ट्रिक एक इंटरफ़ेस बनाना है जो एक सामान्य आधार इंटरफ़ेस का विस्तार करता है ...
public interface LoadFutures extends Map<UUID, Future<LoadResult>> {}
फिर आप कलाकारों से पहले इसे इंस्टाफ के साथ देख सकते हैं ...
Object obj = context.getAttribute(FUTURES);
if (!(obj instanceof LoadFutures)) {
String format = "Servlet context attribute \"%s\" is not of type "
+ "LoadFutures. Its type is %s.";
String msg = String.format(format, FUTURES, obj.getClass());
throw new RuntimeException(msg);
}
return (LoadFutures) obj;
जहाँ तक मुझे पता है, अभी इसके लिए जेनेरिक के बारे में चेतावनियों का दमन करना है; जेएनडी 5 से पहले जेडीके संस्करणों में समर्थित नहीं जेनरिक एक नया प्रोग्रामिंग निर्माण है, इसलिए नए के साथ पुराने निर्माणों के किसी भी मिश्रण में कुछ अप्रत्याशित परिणाम हो सकते हैं।
कंपाइलर प्रोग्रामर को इसके बारे में आगाह करता है, लेकिन अगर प्रोग्रामर को पहले से पता है, तो वे उन खूंखार चेतावनियों को सप्रेसवर्निंग्स का उपयोग करके बंद कर सकते हैं।
एक चेतावनी जिसके द्वारा संकलक इंगित करता है कि यह प्रकार की सुरक्षा सुनिश्चित नहीं कर सकता है। "अनियंत्रित" चेतावनी शब्द भ्रामक है। इसका मतलब यह नहीं है कि चेतावनी किसी भी तरह से अनियंत्रित है। शब्द "अनियंत्रित" इस तथ्य को संदर्भित करता है कि कंपाइलर और रनटाइम सिस्टम में सभी प्रकार की जांच करने के लिए पर्याप्त प्रकार की जानकारी नहीं है जो कि टाइप सुरक्षा सुनिश्चित करने के लिए आवश्यक होगा। इस अर्थ में, कुछ ऑपरेशन "अनियंत्रित" हैं।
"अनियंत्रित" चेतावनियों का सबसे आम स्रोत कच्चे प्रकारों का उपयोग है। "अनियंत्रित" चेतावनियाँ तब जारी की जाती हैं जब किसी वस्तु को कच्चे प्रकार के चर के माध्यम से एक्सेस किया जाता है, क्योंकि कच्चा प्रकार सभी आवश्यक प्रकार की जाँच करने के लिए पर्याप्त प्रकार की जानकारी प्रदान नहीं करता है।
उदाहरण (कच्चे प्रकार के संयोजन में अनियंत्रित चेतावनी):
TreeSet set = new TreeSet();
set.add("abc"); // unchecked warning
set.remove("abc");
warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.TreeSet
set.add("abc");
^
जब ऐड मेथड डाला जाता है तो कंपाइलर को यह नहीं पता होता है कि संग्रह में स्ट्रिंग ऑब्जेक्ट को जोड़ना सुरक्षित है या नहीं। अगर ट्रीसेट एक संग्रह है जिसमें स्ट्रिंग एस (या एक सुपरस्क्रिप्ट टाइप) शामिल है, तो यह सुरक्षित होगा। लेकिन कच्चे प्रकार ट्रीसेट द्वारा प्रदान की गई प्रकार की जानकारी से कंपाइलर नहीं बता सकता है। इसलिए कॉल संभावित रूप से असुरक्षित है और "अनियंत्रित" चेतावनी जारी की जाती है।
"अनियंत्रित" चेतावनियाँ भी तब बताई जाती हैं जब कंपाइलर को एक कास्ट मिलता है जिसका टारगेट टाइप या तो एक पैरामीटराइज्ड टाइप होता है या एक टाइप पैरामीटर होता है।
उदाहरण (एक पैरामीटर प्रकार या प्रकार चर के लिए कलाकारों के साथ संयोजन में एक अनियंत्रित चेतावनी):
class Wrapper<T> {
private T wrapped ;
public Wrapper (T arg) {wrapped = arg;}
...
public Wrapper <T> clone() {
Wrapper<T> clon = null;
try {
clon = (Wrapper<T>) super.clone(); // unchecked warning
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
try {
Class<?> clzz = this.wrapped.getClass();
Method meth = clzz.getMethod("clone", new Class[0]);
Object dupl = meth.invoke(this.wrapped, new Object[0]);
clon.wrapped = (T) dupl; // unchecked warning
} catch (Exception e) {}
return clon;
}
}
warning: [unchecked] unchecked cast
found : java.lang.Object
required: Wrapper <T>
clon = ( Wrapper <T>)super.clone();
^
warning: [unchecked] unchecked cast
found : java.lang.Object
required: T
clon. wrapped = (T)dupl;
एक कास्ट जिसका लक्ष्य प्रकार या तो एक (कंक्रीट या बाउंड वाइल्डकार्ड) पैरामीटर प्रकार है या एक प्रकार का पैरामीटर असुरक्षित है, यदि रनटाइम पर एक गतिशील प्रकार की जांच शामिल है। रनटाइम पर, केवल प्रकार इरेज़र उपलब्ध है, न कि सटीक स्थिर प्रकार जो स्रोत कोड में दिखाई देता है। नतीजतन, कलाकारों का रनटाइम भाग प्रकार के आधार पर किया जाता है, सटीक स्थिर प्रकार पर नहीं।
उदाहरण के लिए, वेपर को कलाकारों की जाँच करेगा कि क्या वस्तु सुपर.क्लोन से लौटी है, एक आवरण है, यह नहीं कि क्या यह एक विशेष प्रकार के सदस्यों के साथ एक आवरण है। इसी प्रकार, प्रकार पैरामीटर T के लिए कलाकारों को रनटाइम पर ऑब्जेक्ट टाइप करने के लिए डाला जाता है, और संभवतः पूरी तरह से अनुकूलित किया जाता है। प्रकार के क्षरण के कारण, रनटाइम सिस्टम रनटाइम पर अधिक उपयोगी प्रकार की जांच करने में असमर्थ है।
एक तरह से, स्रोत कोड भ्रामक है, क्योंकि यह बताता है कि संबंधित लक्ष्य प्रकार के लिए एक कलाकार का प्रदर्शन किया जाता है, जबकि वास्तव में कलाकारों का गतिशील भाग केवल लक्ष्य प्रकार के क्षरण के खिलाफ जांच करता है। "अनियंत्रित" चेतावनी कलाकारों के स्थिर और गतिशील पहलू के बीच इस बेमेल की ओर प्रोग्रामर का ध्यान आकर्षित करने के लिए जारी की जाती है।
कृपया देखें: "अनियंत्रित" चेतावनी क्या है?
@SuppressWarnings एनोटेशन JDK में उपलब्ध तीन निर्मित एनोटेशन में से एक है और जावा 1.5 में @ ऑवरराइड और @ डीपिकेट के साथ जोड़ा गया है।
@SuppressWarnings ने एनॉयलेट किए गए तत्व और सभी प्रोग्राम तत्वों में निर्दिष्ट कंपाइलर चेतावनी को अनदेखा करने या दबाने का निर्देश दिया है। उदाहरण के लिए, यदि किसी वर्ग को किसी विशेष चेतावनी को दबाने के लिए एनोटेट किया जाता है, तो उस वर्ग के अंदर एक विधि में उत्पन्न एक चेतावनी भी अलग हो जाएगी।
आपने @SuppressWarnings ("अनियंत्रित") और @SuppressWarnings ("धारावाहिक"), @SuppressWarnings एनोटेशन के दो सबसे लोकप्रिय उदाहरण देखे होंगे। पूर्व का उपयोग अनियंत्रित कास्टिंग के कारण उत्पन्न चेतावनी को दबाने के लिए किया जाता है जबकि बाद की चेतावनी का उपयोग सीरीयल वर्जनयूआईडी को एक सीरियल क्लास में जोड़ने के बारे में याद दिलाने के लिए किया जाता है।