2009-07-15 11 views

उत्तर

335

कभी कभी जावा जेनरिक सिर्फ तुम क्या आप चाहते हैं नहीं करता है, और आप को प्रभावी ढंग से संकलक है कि क्या तुम सच में कर रहे हैं निष्पादन समय पर कानूनी हो जाएगा बताने के लिए की जरूरत है।

मुझे आमतौर पर यह दर्द होता है जब मैं एक सामान्य इंटरफ़ेस का मज़ाक उड़ा रहा हूं, लेकिन अन्य उदाहरण भी हैं। यह आमतौर पर चेतावनी से बचने के बजाय चेतावनी से बचने का प्रयास करने लायक है (Java Generics FAQ यहां सहायता करता है) लेकिन कभी-कभी संभव है, तो यह कोड को इतना आकार से बाहर करता है कि चेतावनी को दबाकर साफ किया जाता है। हमेशा उस मामले में एक व्याख्यात्मक टिप्पणी जोड़ें!

उसी जेनरिक FAQ के पास इस विषय पर "What is an "unchecked" warning?" से शुरू होने वाले कई अनुभाग हैं - यह पढ़ने योग्य है।

+8

कुछ मामलों में, आप YourClazz.class.cast() का उपयोग करके इसे से बच सकते हैं। एकल जेनेरिक तत्व कंटेनर के लिए काम करता है लेकिन संग्रह के लिए नहीं। – akarnokd

+0

या अधिमानतः वाइल्डकार्ड जेनेरिक '(YourClazz ) का उपयोग करें' - जावा कभी भी ऐसे जानवरों के बारे में चेतावनी नहीं देता है क्योंकि वे सुरक्षित हैं। हालांकि यह हमेशा काम नहीं करेगा (विवरण के लिए जेनेरिक एफएक्यू देखें)। – xfix

39

यह अनचेक जेनेरिक ऑपरेशंस (अपवाद नहीं), जैसे कि कास्ट के बारे में संकलन चेतावनियों को दबाने के लिए एक टिप्पणी है। यह अनिवार्य रूप से तात्पर्य है कि प्रोग्रामर इनके बारे में अधिसूचित नहीं होना चाहता था, जो कि किसी विशेष कोड को संकलित करते समय पहले ही जानते हैं।

आप इस विशिष्ट एनोटेशन यहाँ के बारे में अधिक पढ़ सकते हैं:

:

SuppressWarnings

साथ ही, ओरेकल एनोटेशन के उपयोग यहाँ पर कुछ ट्यूटोरियल प्रलेखन प्रदान करता है

वे इसे डाल के रूप में,

" 'अनियंत्रित' चेतावनी जब जेनरिक के आगमन (सबक शीर्षक जेनेरिक्स में चर्चा) से पहले लिखा विरासत कोड के साथ इंटरफ़ेस हो सकता है।"

9

SuppressWarning एनोटेशन का उपयोग एनोटेटेड तत्व के लिए कंपाइलर चेतावनियों को दबाने के लिए किया जाता है। विशेष रूप से, unchecked श्रेणी अनचेक प्रकार के कारणों के परिणामस्वरूप उत्पन्न संकलक चेतावनियों के दमन की अनुमति देता है।

+0

आपका SupressWarning लिंक मर चुका है; यहां एक विकल्प है: http://docs.oracle.com/javase/specs/jls/se6/html/interfaces.html#9.6.1.5 –

3

जहाँ तक मुझे पता है, अब इसे जेनेरिक के बारे में चेतावनियों को दबाने के साथ करना है; जेनरिक, JDK 5 से पहले JDK संस्करणों में समर्थित नहीं एक नई प्रोग्रामिंग निर्माण कर रहे हैं तो नए लोगों के साथ पुराने निर्माणों में से किसी घोला जा सकता है कुछ अप्रत्याशित परिणाम उत्पन्न कर सकता है।

संकलक इसके बारे में प्रोग्रामर ने चेतावनी दी है, लेकिन अगर प्रोग्रामर पहले से ही जानता है, वे उन खतरनाक चेतावनी SuppressWarnings का उपयोग कर बंद कर सकते हैं।

+1

जेडीके 5 नया है? इसने अपनी अधिकांश सेवा जीवन अवधि समाप्त कर दी है। –

+0

मुझे पता है कि जेडीके 5 पुराना है, मेरा मतलब यह था कि, यह इस अर्थ में नया है कि उसने जावा में नई विशेषताएं पेश कीं, पहले जेडीके 4 में पेश नहीं की गई थी। यह भी ध्यान दें कि जेडीके 5 छोड़ने से पहले वे अभी भी जेडीके 7 का इंतजार कर रहे हैं जेडीके 6 को गले लगाने के लिए पीछे, मैं कारण नहीं कर सकता! – BakerTheHacker

17

यह भी अर्थ हो सकता है कि मौजूदा जावा प्रकार सिस्टम संस्करण अपने मामले के लिए पर्याप्त नहीं है। इसे ठीक करने के लिए कई JSR propositions/हैक हैं: टोकन टाइप करें, Super Type Tokens, क्लास.कास्ट()।

यदि आपको वास्तव में इस दमन की आवश्यकता है, तो इसे यथासंभव कम करें (उदाहरण के लिए इसे कक्षा में या लंबी विधि पर न रखें)। एक उदाहरण:

public List<String> getALegacyListReversed() { 
    @SuppressWarnings("unchecked") List<String> list = 
     (List<String>)legacyLibrary.getStringList(); 

    Collections.reverse(list); 
    return list; 
} 
5

आप संकलक चेतावनियों को दबा सकते हैं और जेनेरिक को बता सकते हैं कि आपके द्वारा लिखे गए कोड के अनुसार कानूनी है।

उदाहरण:

@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; 
} 
5

एक चाल एक अंतरफलक है कि एक सामान्य आधार इंटरफेस फैली बनाने के लिए है ...

public interface LoadFutures extends Map<UUID, Future<LoadResult>> {} 

तो फिर तुम डाली से पहले instanceof के साथ यह जाँच कर सकते हैं ...

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; 
7

बस: यह एक चेतावनी है जिसके द्वारा संकलक इंगित करता है कि यह प्रकार की सुरक्षा सुनिश्चित नहीं कर सकता है। उदाहरण के लिए

जेपीए सेवा विधि:

@SuppressWarnings("unchecked") 
public List<User> findAllUsers(){ 
    Query query = entitymanager.createQuery("SELECT u FROM User u"); 
    return (List<User>)query.getResultList(); 
} 

मैं @SuppressWarnings anotate didn'n हैं ("अनियंत्रित") यहाँ है, यह लाइन, जहां मैं अपने ResultList लौटना चाहते के साथ एक समस्या होगी।

शॉर्टकट प्रकार-सुरक्षा का अर्थ है: यदि प्रोग्राम त्रुटियों और चेतावनियों के बिना संकलित होता है तो यह प्रोग्राम टाइप-सुरक्षित माना जाता है और रनटाइम पर किसी भी अप्रत्याशित क्लासकास्ट अपवाद को नहीं बढ़ाता है।

मैं निर्माण http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html

+2

यह स्थिति के लिए एक अच्छा उदाहरण है जहां हमें SuppressWarnings का उपयोग करने की आवश्यकता है। – Jimmy

0

जावा में पर, जेनरिक प्रकार विलोपन के माध्यम से लागू किया जाता है। उदाहरण के लिए, निम्नलिखित कोड।

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); 

और जैसा कि जावा कम्पाइलर एक अंतर्निहित डाली डाला JVM एक अप्रत्याशित 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<>(); 
@SuppressWarnings("unchecked") 
public static <T> Optional<T> empty() { 
    return (Optional<T>) EMPTY; 
} 

यह कलाकारों, सुरक्षित है।

संबंधित मुद्दे