संग्रह। रिक्त सूची () एक सूची देता है <वस्तु>?


269

जेनेरिक प्रकार के मापदंडों को लागू करने के लिए जावा के नियम को नेविगेट करने में मुझे कुछ परेशानी हो रही है। निम्नलिखित वर्ग पर विचार करें, जिसमें एक वैकल्पिक सूची पैरामीटर है:

import java.util.Collections;
import java.util.List;

public class Person {
  private String name;
  private List<String> nicknames;

  public Person(String name) {
    this(name,Collections.emptyList());
  }

  public Person(String name,List<String> nicknames) {
    this.name = name;
    this.nicknames = nicknames;
  }
}

मेरा जावा कंपाइलर निम्नलिखित त्रुटि देता है:

Person.java:9: The constructor Person(String, List<Object>) is undefined

लेकिन Collections.emptyList()रिटर्न प्रकार <T> List<T>, नहीं List<Object>। कलाकारों को जोड़ने से कोई फायदा नहीं होता

public Person(String name) {
  this(name,(List<String>)Collections.emptyList());
}

पैदावार

Person.java:9: inconvertible types

के EMPTY_LISTबजाय का उपयोग करemptyList()

public Person(String name) {
  this(name,Collections.EMPTY_LIST);
}

पैदावार

Person.java:9: warning: [unchecked] unchecked conversion

जबकि निम्नलिखित परिवर्तन से त्रुटि दूर हो जाती है:

public Person(String name) {
  this.name = name;
  this.nicknames = Collections.emptyList();
}

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

अतिरिक्त क्रेडिट के लिए: EMPTY_LISTइसका विरोध करना कब उचित है emptyList()?


1
सभी जावा जेनरिक से संबंधित प्रश्नों के लिए, मैं मौरिस नाफ्टलिन, फिलिप वाडलर द्वारा " जावा जेनरिक एंड कलेक्शंस " की अत्यधिक अनुशंसा करता हूं ।
जुलिएन चास्टांग

जवाबों:


447

आप जिस समस्या का सामना कर रहे हैं, वह यह है कि भले ही यह विधि emptyList()वापस आए List<T>, लेकिन आपने इसे प्रकार के साथ प्रदान नहीं किया है, इसलिए यह लौटने में चूक करता है List<Object>। आप टाइप पैरामीटर की आपूर्ति कर सकते हैं, और आपका कोड इस तरह व्यवहार कर सकता है:

public Person(String name) {
  this(name,Collections.<String>emptyList());
}

अब जब आप सीधे असाइनमेंट कर रहे हैं, तो कंपाइलर आपके लिए सामान्य प्रकार के मापदंडों का पता लगा सकता है। इसे प्रकार का अनुमान कहा जाता है। उदाहरण के लिए, यदि आपने ऐसा किया है:

public Person(String name) {
  List<String> emptyList = Collections.emptyList();
  this(name, emptyList);
}

तब emptyList()कॉल सही तरीके से वापस आ जाएगी List<String>


12
समझ गया। एमएल की दुनिया से आ रहा है, यह मेरे लिए अजीब है कि जावा सही प्रकार का अनुमान नहीं लगा सकता है: औपचारिक पैरामीटर का प्रकार और रिक्त प्रकार का रिक्त स्थान स्पष्ट रूप से अस्वीकार्य है। लेकिन मुझे लगता है कि टाइपकर्ता केवल "बेबी स्टेप्स" ही ले सकता है।
क्रिस कॉनवे

5
कुछ सरल मामलों में, कंपाइलर के लिए इस मामले में लापता प्रकार के पैरामीटर का अनुमान लगाना संभव हो सकता है - लेकिन यह खतरनाक हो सकता है। यदि अलग-अलग मापदंडों के साथ विधि के कई संस्करण मौजूद हैं, तो आप गलत कॉलिंग को समाप्त कर सकते हैं। और दूसरा भी अभी तक मौजूद नहीं हो सकता है ...
बिल माइकेल

13
वह संकेतन "संग्रह। <स्ट्रिंग> खाली सूची ()" वास्तव में अजीब है, लेकिन समझ में आता है। Enum की तुलना में आसान <E, Enum <E >> का विस्तार करता है। :)
थियागो ने

12
जावा 8 में अब एक प्रकार के पैरामीटर की आवश्यकता नहीं है (जब तक कि संभावित सामान्य प्रकारों में अस्पष्टता न हो)।
विटाली फेडोरेंको

9
दूसरा स्निपेट अच्छी तरह से प्रकार का अनुमान दिखाता है, लेकिन संकलन नहीं करेगा। thisकंस्ट्रक्टर में कॉल को पहले स्टेटमेंट होना चाहिए।
अर्जन

99

आप उपयोग करना चाहते हैं:

Collections.<String>emptyList();

यदि आप स्रोत के लिए देखते हैं कि आप किस रिक्त स्थान पर देखते हैं कि यह वास्तव में सिर्फ एक करता है

return (List<T>)EMPTY_LIST;

26

इस हस्ताक्षर में वैकेंसी विधि है:

public static final <T> List<T> emptyList()

इससे <T>पहले कि शब्द सूची का अर्थ है कि यह जेनेरिक पैरामीटर टी के मूल्य को चर के प्रकार से प्रभावित करता है जिसका परिणाम सौंपा गया है। तो इस मामले में:

List<String> stringList = Collections.emptyList();

रिटर्न मान को स्पष्ट रूप से एक प्रकार के चर द्वारा संदर्भित किया जाता है List<String>, इसलिए संकलक यह पता लगा सकता है। इस मामले में:

setList(Collections.emptyList());

कंपाइलर के लिए जेनेरिक प्रकार का पता लगाने के लिए कोई स्पष्ट रिटर्न वैरिएबल नहीं है, इसलिए यह चूक करता है Object

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.