जावा की छिपी विशेषताएं


295

C # के हिडन फीचर्स को पढ़ने के बाद मैंने सोचा कि जावा के कुछ छिपे हुए फीचर्स क्या हैं?


17
ध्यान दें कि इन छिपी हुई विशेषताओं का उपयोग करना हमेशा एक महान विचार नहीं है; अक्सर बार वे आश्चर्यचकित होते हैं और आपके कोड को पढ़ने वाले दूसरों को भ्रमित करते हैं।
केविन बोर्रिलियन

1
आपको (किसी को) C # प्रश्न जैसे प्रश्न निकाय में बड़े करीने से उत्तर देना चाहिए।
ripper234

जवाबों:


432

डबल ब्रेस इनिशियलाइज़ेशन ने मुझे कुछ महीने पहले आश्चर्यचकित कर दिया जब मैंने पहली बार इसकी खोज की, इसके बारे में पहले कभी नहीं सुना।

थ्रेडलोकल को आमतौर पर व्यापक रूप से प्रति-थ्रेड स्थिति को संग्रहीत करने के तरीके के रूप में नहीं जाना जाता है।

चूँकि JDK 1.5 जावा में बहुत अच्छी तरह से लागू किया गया है और सिर्फ ताले से परे मजबूत संगामिति उपकरण हैं, वे java.util.concurrent में रहते हैं और एक विशेष रूप से दिलचस्प उदाहरण java.util.concurrent.atomic उप-पैकेज है जो थ्रेड-सुरक्षित प्राइमेटिव है जो तुलना को लागू करता है। -और-स्वैप ऑपरेशन और इन ऑपरेशन के वास्तविक देशी हार्डवेयर समर्थित संस्करणों के लिए मैप कर सकते हैं।


40
डबल-ब्रेस इनिशियलाइज़ेशन ... अजीब ... मैं उस विशेष मुहावरे को व्यापक रूप से अपनाने से सावधान रहूंगा, क्योंकि यह वास्तव में ऑब्जेक्ट का एक अनाम उपवर्ग बनाता है, जिससे भ्रामक बराबरी / हैशकोड की समस्या हो सकती है। java.util.concurrent वास्तव में एक शानदार पैकेज है।
एमबी।

6
मैंने जावा को पढ़ाया है, और यह पहली बार है जब मैं इस सिंटैक्स पर आया हूँ ... जो आपको दिखाने के लिए जाता है कि आप कभी भी सीखना बंद न करें = 8-)
युवल

49
ध्यान दें कि यदि आप इस "डबल ब्रेस" मुहावरे (या यदि हम इसे इसके वास्तविक नाम - इनिशियल ब्लॉक के साथ एनॉनिमस क्लास कहते हैं) के साथ आरंभ किए गए एक संग्रह का संदर्भ बनाए रखते हैं, तो आप स्पष्ट रूप से बाहरी वस्तु का संदर्भ रखते हैं, जो आपकी स्वादिष्ट स्मृति का कारण बन सकती है लीक। मैं इसे पूरी तरह से टालने की सलाह दूंगा।
ddimitrov 13

51
"डबल-ब्रेस इनिशियलाइज़ेशन" एक अनाम आंतरिक वर्ग बनाने के लिए एक बहुत ही व्यंजनापूर्ण नाम है, जो वास्तव में हो रहा है और इस पर ध्वनि बना रहा है जैसे कि आंतरिक कक्षाओं को इस तरह इस्तेमाल करने का इरादा था। यह एक ऐसा पैटर्न है जिसे मैं छिपाना पसंद करूंगा।
erickson

11
लगभग, यह वास्तव में एक स्थिर ब्लॉक नहीं है, लेकिन एक "इनिशलाइज़र ब्लॉक" है जो अलग है क्योंकि यह एक अलग समय पर निष्पादित होता है (अधिक विवरण के लिए मेरे द्वारा दिए गए लिंक को देखें)
बोरिस टेरिक

279

संयुक्त संघ प्रकार पैरामीटर विचरण में:

public class Baz<T extends Foo & Bar> {}

उदाहरण के लिए, यदि आप एक पैरामीटर लेना चाहते हैं जो तुलनात्मक और संग्रह दोनों है:

public static <A, B extends Collection<A> & Comparable<B>>
boolean foo(B b1, B b2, A a) {
   return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);
}

यदि दो दिए गए संग्रह समान हैं या यदि उनमें से किसी एक में दिए गए तत्व हैं, तो यह गलत है या नहीं तो यह विरोधाभासी तरीका सही है। ध्यान देने वाली बात यह है कि आप तर्कों और संग्रह दोनों की विधियों को b1 और b2 पर लागू कर सकते हैं।


इसके लिए मेरा पसंदीदा उपयोग तब है जब आपको एक ऐसी विधि की आवश्यकता होती है जो एक परिशिष्ट रूप से स्वीकार कर लेता है।
नील कॉफ़ी

5
क्या इसके बजाय वहां "या" होना संभव है?
मेनस्ट्रिंगरग्स

9
@Grasper: नहीं, या (असंतुष्ट संघ) उस संदर्भ में प्रदान नहीं किया गया है। लेकिन आप इसके बजाय या तो <a, B> जैसे असंतुष्ट संघ डेटाटाइप का उपयोग कर सकते हैं। यह प्रकार एक जोड़ी <A, B> प्रकार का दोहरी है। इस तरह के डेटाटाइप के उदाहरण के लिए कार्यात्मक जावा लाइब्रेरी या स्काला कोर लाइब्रेरी देखें।
अप्रत्यक्ष

5
आपको यह कहना चाहिए कि आप केवल एक वर्ग और कई इंटरफेस का विस्तार करते हैं -> पब्लिक क्लास बाज <टी क्लैज़ एंड इंटरफेस 1 और इंटरफ़ेसआई ... और न ही क्लास बाज़ <टी क्लैज़ 1 और क्लैज़ी> का विस्तार करता है
जॉनजॉना

220

मैं उदाहरण के शुरुआती दिनों से हैरान था। मैं कुछ कोड-आधारित विधियों को हटा रहा था और कई उदाहरण इनिशियलाइज़र बना रहा था:

public class App {
    public App(String name) { System.out.println(name + "'s constructor called"); }

    static { System.out.println("static initializer called"); }

    { System.out.println("instance initializer called"); }

    static { System.out.println("static initializer2 called"); }

    { System.out.println("instance initializer2 called"); }

    public static void main( String[] args ) {
        new App("one");
        new App("two");
  }
}

निष्पादन mainविधि प्रदर्शित होगी:

static initializer called
static initializer2 called
instance initializer called
instance initializer2 called
one's constructor called
instance initializer called
instance initializer2 called
two's constructor called

मुझे लगता है कि ये उपयोगी होगा यदि आपके पास कई कंस्ट्रक्टर थे और उन्हें सामान्य कोड की आवश्यकता थी

वे आपकी कक्षाओं को आरंभीकृत करने के लिए सिंटैक्टिक शुगर भी प्रदान करते हैं:

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

Map<String,String> codes = new HashMap<String,String>(){{ 
  put("1","one"); 
  put("2","two");
}};

38
एक स्पष्ट पद्धति पर इसका लाभ उठाने की आवश्यकता है, अगर कोई एक निर्माता को बाद में जोड़ता है तो उन्हें init () को कॉल करने के लिए याद रखने की आवश्यकता नहीं है; वह अपने आप हो जाएगा। यह भविष्य के प्रोग्रामर द्वारा त्रुटियों को रोक सकता है।
श्री चमकदार और नई 安

40
इसके अलावा, एक init () विधि के विपरीत, यह अंतिम फ़ील्ड को इनिशियलाइज़ कर सकता है।
डार्रोन

2
यदि आप कक्षा का विस्तार करते हैं और विभिन्न बच्चों को तुरंत पढ़ाते हैं तो क्या होगा? क्या यह अभी भी उसी तरीके से व्यवहार करेगा?
केजर

12
लोग अक्सर प्रमाणपत्र को नापसंद करते हैं (उदाहरण के लिए stackoverflow.com/questions/281100/281127#281127 ) और विशेषकर उनकी तकनीकी खूबियों पर सवाल उठाते हैं। लेकिन अगर यहां अधिक प्रोग्रामर ने अपने एससीजेपी के लिए अध्ययन किया था, तो यह इतने से "छिपी हुई विशेषता" नहीं माना जाएगा। ;-)
जोनीक

12
मैं शर्त लगाता हूं कि "24 घंटे में जावा" पुस्तक में यह "स्पष्ट विशेषता" है। और अधिक पढ़ें
:)

201

JDK 1.6_07 + में VisualVM (बिन / jvisualvm.exe) नामक एक ऐप शामिल है, जो कई टूल्स के ऊपर एक अच्छा GUI है। यह JConsole की तुलना में अधिक व्यापक लगता है।


और इसमें एक प्लगइन है (यह एक netbeans thingie है) जो इसे Jconsole प्लगइन्स का उपयोग करने की अनुमति देता है। काफी अच्छा।
थोरबजर्न रेवन एंडरसन

VisualVM कटा हुआ रोटी के बाद से सबसे अच्छी बात है, वास्तव में! बहुत बुरा यह सब सुविधाओं नहीं है जब JDK 1.5 के खिलाफ चल रहा है
सैंडोस

मुझे कुछ परिस्थितियों में VisualVM धीमा या अनुपयोगी लगता है। वाणिज्यिक YourKit में यह समस्या नहीं है, लेकिन दुर्भाग्य से मुक्त नहीं है।
रोहतक

JDK 1.6.0_22 और बाद के विज़ुअल वीएम के अधिक हाल के संस्करणों में बहुत सुधार हुआ है। मैं शर्त लगा सकता हूँ कि JDK1.7 का इससे भी बेहतर संस्करण है।
djangofan


156

ज्यादातर लोगों के लिए मैं जावा डेवलपर पदों के लिए साक्षात्कार देता हूं लेबल वाले ब्लॉक बहुत आश्चर्यचकित करते हैं। यहाँ एक उदाहरण है:

// code goes here

getmeout:{
    for (int i = 0; i < N; ++i) {
        for (int j = i; j < N; ++j) {
            for (int k = j; k < N; ++k) {
                //do something here
                break getmeout;
            }
        }
    }
}

gotoजावा में किसने कहा कि यह केवल एक खोजशब्द है? :)


2
खैर, मैं इसके बजाय इसे कई तरीकों से करने का विकल्प रखना पसंद करूंगा। उदाहरण के लिए, मैंने लोगों को System.exit (1) का उपयोग करते हुए देखा; सर्वलेट और EJB कोड में, लेकिन इसका मतलब यह नहीं है कि हमें System.exit () को हटा देना चाहिए; JDK से, है ना?
जॉर्जी बोलिउबा

31
कुछ परिस्थितियों में, नेस्टेड लूप निर्माण के भीतर, बाहरी लूप के अगले पुनरावृत्ति को जारी रखने के लिए उपयोगी हो सकता है। यह इस सुविधा का एक उचित उपयोग होगा।

75
विशेष रूप से कई प्रोग्रामर (और शायद बस के रूप में) के लिए अज्ञात है कि आप वास्तव में लेबल कर सकते हैं और किसी भी पुराने ब्लॉक को तोड़ सकते हैं। इसमें लूप होना जरूरी नहीं है - आप बस कुछ मनमाने ब्लॉक को परिभाषित कर सकते हैं, इसे एक लेबल दे सकते हैं, और इसके साथ ब्रेक का उपयोग कर सकते हैं।
नील कॉफ़ी

27
यह एक गोटो नहीं है, यह केवल एक पूर्व पुनरावृत्ति पर लौट सकता है (यानी: आप आगे कूद नहीं सकते)। यह वही तंत्र है जो तब होता है जब एक पुनरावृत्ति झूठी होती है। कहने को जावा का गोटो है, किसी भी भाषा को कहने जैसा है जिसका कंपाइलर एक JUMP इंस्ट्रक्शन तैयार करता है।
लाश

4
तो आप समस्याओं को हल करने और डिजाइनों के माध्यम से सोचने के लिए योग्यता के बजाय जावा ट्रिविया पर आधारित साक्षात्कार करते हैं। मुझे यकीन है कि मैं कभी भी आपकी कंपनी के साथ साक्षात्कार नहीं करूँगा। :)
जावीद जमाते २०

144

जेडीके 1.5 के बाद से सहसंयोजक वापसी प्रकार के बारे में कैसे ? यह बहुत खराब प्रचारित है, क्योंकि यह एक अलौकिक जोड़ है, लेकिन जैसा कि मैं इसे समझता हूं, जेनरिक के लिए काम करना नितांत आवश्यक है।

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

class Souper {
    Collection<String> values() {
        ...
    }
}

class ThreadSafeSortedSub extends Souper {
    @Override
    ConcurrentSkipListSet<String> values() {
        ...
    }
}

आप उपवर्ग के कॉल कर सकते हैं valuesविधि और एक क्रमबद्ध धागा सुरक्षित प्राप्त Setकी Stringरों नीचे डाली बिना करने के लिए ConcurrentSkipListSet


क्या आप एक उदाहरण उपयोग प्रदान कर सकते हैं?
एलन लालडे

24
मैं इसका भरपूर उपयोग करता हूं। क्लोन () एक महान उदाहरण है। यह ऑब्जेक्ट वापस करने वाला है, जिसका अर्थ है कि आपको उदाहरण के लिए (सूची) सूची कहना होगा। क्लोन ()। हालाँकि यदि आप सूची क्लोन () {...} के रूप में घोषित करते हैं, तो कलाकार अनावश्यक है।
जेसन कोहेन

142

अंत में ब्लॉक में नियंत्रण का हस्तांतरण किसी भी अपवाद को दूर फेंकता है। निम्न कोड RuntimeException को नहीं फेंकता है - यह खो गया है।

public static void doSomething() {
    try {
      //Normally you would have code that doesn't explicitly appear 
      //to throw exceptions so it would be harder to see the problem.
      throw new RuntimeException();
    } finally {
      return;
    }
  }

से http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html


7
यह बुरा है, लेकिन यह भी एक तार्किक परिणाम है कि आखिरकार यह कैसे काम करता है। कोशिश / पकड़ / अंत में प्रवाह नियंत्रण वह करता है जो इसे करने का इरादा है, लेकिन केवल कुछ सीमाओं के भीतर। इसी तरह, आपको सावधान रहना होगा कि कैच / अंततः ब्लॉक के अंदर कोई अपवाद न हो, या आप मूल अपवाद को भी फेंक देंगे। और यदि आप कोशिश ब्लॉक के अंदर System.exit () करते हैं, तो अंत में ब्लॉक नहीं कहा जाएगा। यदि आप सामान्य प्रवाह को तोड़ते हैं, तो आप सामान्य प्रवाह को तोड़ देते हैं ...
नील कॉफ़ी

अंत में {वापसी का उपयोग न करें; } लेकिन अंत में {रिटर्न के बिना कोड}। यह तर्कसंगत है, जैसा कि अपवाद होने पर अंत में निष्पादित करने का इरादा भी है, और अपवाद हैंडलर के रूप में वापसी का एकमात्र संभावित अर्थ अपवाद को अनदेखा करना होगा और - वास्तव में - वापसी।
extraneon

21
यह एक छिपी हुई विशेषता की तुलना में "गेटचा" के अधिक लगता है, हालांकि ऐसे तरीके हैं जो इसे एक के रूप में इस्तेमाल किया जा सकता है, इस पद्धति का उपयोग करना एक अच्छा विचार नहीं होगा।
davenpcj

यदि आप ऐसा करते हैं तो ग्रहण एक चेतावनी का उत्सर्जन करता है। मैं ग्रहण के साथ हूँ। यदि आप एक अपवाद को पकड़ना चाहते हैं ... तो एक अपवाद को पकड़ लें।
हेलियोस

यही कारण है कि आप गंदे कोड के लिए भुगतान करते हैं जो विधि के बीच से लौटता है। लेकिन फिर भी एक अच्छा उदाहरण है।
रोस्टिस्लाव मैटल

141

किसी को भी इस तरह से लागू होने का उल्लेख नहीं देखा गया है कि अशक्त के लिए जाँच आवश्यक नहीं है।

के बजाय:

if( null != aObject && aObject instanceof String )
{
    ...
}

महज प्रयोग करें:

if( aObject instanceof String )
{
    ...
}

9
यह शर्म की बात है कि यह इस तरह की एक छोटी-सी विशेषता है। मैंने कोड के पहले ब्लॉक के समान बहुत सारे कोड देखे हैं।
पीटर डॉल्बर्ग

4
ऐसा इसलिए है क्योंकि जावा में एक विशेष (छिपा हुआ) अशक्त प्रकार है जिसे आप नहीं देखते हैं, न ही संदर्भित कर सकते हैं।
निक हिस्टिरोव

C / C ++ में freeing या deleteing से पहले null के लिए जाँच करना क्या बदतर है । ऐसी मौलिक अवधारणा।
थॉमस ईडिंग

134

Enums में अनुमति देने के तरीकों और निर्माणकर्ताओं ने मुझे आश्चर्यचकित किया। उदाहरण के लिए:

enum Cats {
  FELIX(2), SHEEBA(3), RUFUS(7);

  private int mAge;
  Cats(int age) {
    mAge = age;
  }
  public int getAge() {
    return mAge;
   }
}

यहां तक ​​कि आपके पास "निरंतर विशिष्ट वर्ग निकाय" हो सकता है जो विशिष्ट एनम मान को विधियों को ओवरराइड करने की अनुमति देता है।

अधिक प्रलेखन यहाँ


20
वास्तव में वास्तव में बहुत बढ़िया सुविधा - यह एम्स को OO बनाती है और बहुत ही स्वच्छ तरीके से कई प्रारंभिक समस्याओं को हल करती है।
बिल के

5
सिंगलटन के रूप में Enum? केवल एक मूल्य के साथ Enum?
जॉर्जियाई बोल्युबा

6
Georgy: सिंगलटन ऑब्जेक्ट का एक उदाहरण है, न कि एक मान वाला ऑब्जेक्ट।
22

20
@ गौरी: यह भी देखें जोशुआ बलोच के प्रभावी जावा में आइटम 3 (2 एड); "जबकि इस दृष्टिकोण को व्यापक रूप से अपनाया जाना बाकी है, एकल-तत्व एनम प्रकार एक सिंगलटन को लागू करने का सबसे अच्छा तरीका है।"
जोनीक

3
माइनर नाइटपिक: mAgeअंतिम होना चाहिए। एनमों में गैर-अंतिम फेल्ड्स के लिए शायद ही कोई कारण हो।
जोकिम सॉयर

121

जेनेरिक विधियों के प्रकार को स्पष्ट रूप से निर्दिष्ट किया जा सकता है:

Collections.<String,Integer>emptyMap()

10
और भगवान द्वारा यह बदसूरत और भ्रमित है। और सुरक्षा के लिए अप्रासंगिक।
क्रिस ब्रॉडफुट

8
मुझे यह पसंद है। यह आपके कोड को थोड़ा और स्पष्ट करता है और गरीबों के लिए अधिक स्पष्ट होता है, जिन्हें इसे एक या दो साल में बनाए रखना होगा।
एक्सट्रोनॉन

6
यह वास्तव में उन स्थितियों में बहुत उपयोगी है जहां आपने एक स्थिर सामान्य विधि घोषित की है public static <T> T foo(T t)। फिर आप कॉल कर सकते हैंClass.<Type>foo(t);
फ़िनबार

किसी कारण से यह सांख्यिकीय रूप से आयातित विधियों के साथ काम नहीं करता है .. मुझे आश्चर्य है कि क्यों।
oksayt

यह विशेष रूप से उपयोगी है जब वापसी के साथ टर्नरी आईएफ का उपयोग किया जाता है। उदाहरण के लिए return set1.equals(set2) ? new ArrayList<String>(set1) : Collections.<String>emptyList()। यह कुछ विधि चालानों के लिए भी उपयोगी है जहाँ एक साधारण संग्रह .emptyMap () संकलन त्रुटि देगा।
एंड्रियास होल्स्टेनसन

112

इंटरफ़ेस लागू करने के लिए आप एनम का उपयोग कर सकते हैं।

public interface Room {
   public Room north();
   public Room south();
   public Room east();
   public Room west();
}

public enum Rooms implements Room {
   FIRST {
      public Room north() {
         return SECOND;
      }
   },
   SECOND {
      public Room south() {
         return FIRST;
      }
   }

   public Room north() { return null; }
   public Room south() { return null; }
   public Room east() { return null; }
   public Room west() { return null; }
}

संपादित करें: वर्षों बाद ...।

मैं यहाँ इस सुविधा का उपयोग करता हूँ

public enum AffinityStrategies implements AffinityStrategy {

https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/vanilla/java/affinity/AffinityStrategies.java

एक इंटरफ़ेस का उपयोग करके, डेवलपर्स अपनी रणनीतियों को परिभाषित कर सकते हैं। एक enumसाधन का उपयोग करके मैं लोगों में निर्मित एक संग्रह (पांच में से) को परिभाषित कर सकता हूं।


27
यह पागलपन है। (+1)
सेफेलोपॉड

12
@ एरियन यह पागलपन नहीं है। इस। है। JAVAAAAAAHHHH!
स्लीज़िका

1
WHAAAAAT नहीं, मैं एड्रियन के साथ हूं। यह जावा नहीं है। यह पागलपन है। मैं इसका उपयोग करने के लिए मर रहा हूं।
स्लीज़िका

104

Java 1.5 के रूप में, Java में अब वेरिएबल एरिटी के फंक्शन्स को लिखने के लिए बहुत अधिक क्लीनर सिंटैक्स है। इसलिए, केवल एक सरणी पास करने के बजाय, अब आप निम्नलिखित कार्य कर सकते हैं

public void foo(String... bars) {
   for (String bar: bars)
      System.out.println(bar);
}

बार स्वचालित रूप से निर्दिष्ट प्रकार के सरणी में परिवर्तित हो जाते हैं। एक बड़ी जीत नहीं, लेकिन फिर भी एक जीत।


23
इस बारे में महत्वपूर्ण बात यह है कि विधि को कॉल करते समय, आप लिख सकते हैं: फू ("पहला", "दूसरा", "तीसरा")
स्टीव आर्मस्ट्रांग

9
इसलिए पुरानी दुनिया को फिर से लिखा जा सकता है; सार्वजनिक स्थैतिक शून्य मुख्य (स्ट्रिंग ... आर्ग्स) {System.out.println ("हैलो वर्ल्ड!"); }
Karussell

@ कर्कसेल शायद, लेकिन ऐसा लगता है कि तर्क अप्रासंगिक हैं: पी
केली एल्टन

93

मेरा पसंदीदा: सभी थ्रेड स्टैक के निशान को मानक रूप से डंप करें।

windows: CTRL- Breakआपके जावा cmd / कंसोल विंडो में

यूनिक्स: kill -3 PID


15
यूनिक्स में भी ctrl- \। या JDK से jstack का उपयोग करें।
टॉम हॉल्टिन -

9
धन्यवाद, आपने मुझे सिखाया कि मेरे कीबोर्ड में एक Breakकुंजी है।
एमी बी

2
विंडोज़ पर, CTRL-BREAK केवल तभी काम करता है जब आपके पास वर्तमान कंसोल विंडो में चलने वाली प्रक्रिया हो। आप इसके बजाय JAVA_HOME / bin / jstack.exe का उपयोग कर सकते हैं। बस इसे विंडोज प्रक्रिया आईडी के साथ प्रदान करें।
जावीद जमाते

मुझे लगा कि यह मार रहा था -सिक्क्विट
निक

@ निक, हां SIGQUIT आमतौर पर # 3 संकेत है।
क्रिस माजोला

89

कुछ लोगों ने उदाहरण इनिशियलाइज़र के बारे में पोस्ट किया है, यहाँ इसके लिए एक अच्छा उपयोग है:

Map map = new HashMap() {{
    put("a key", "a value");
    put("another key", "another value");
}};

यदि आप किसी त्वरित और सरल कार्य को कर रहे हैं तो मानचित्रों को आरंभ करने का एक त्वरित तरीका है।

या इसका उपयोग एक त्वरित स्विंग फ्रेम प्रोटोटाइप बनाने के लिए किया जाता है:

JFrame frame = new JFrame();

JPanel panel = new JPanel(); 

panel.add( new JLabel("Hey there"){{ 
    setBackground(Color.black);
    setForeground( Color.white);
}});

panel.add( new JButton("Ok"){{
    addActionListener( new ActionListener(){
        public void actionPerformed( ActionEvent ae ){
            System.out.println("Button pushed");
        }
     });
 }});


 frame.add( panel );

बेशक इसका दुरुपयोग किया जा सकता है:

    JFrame frame = new JFrame(){{
         add( new JPanel(){{
               add( new JLabel("Hey there"){{ 
                    setBackground(Color.black);
                    setForeground( Color.white);
                }});

                add( new JButton("Ok"){{
                    addActionListener( new ActionListener(){
                        public void actionPerformed( ActionEvent ae ){
                            System.out.println("Button pushed");
                        }
                     });
                 }});
        }});
    }};

किसी तरह, यह थोड़ा सा है जैसे कि "कीवर्ड" (कार्यक्षमता, वास्तव में) के साथ जावा में जोड़ा गया है। बहुत आसान हो सकता है, हाल ही में मैंने ग्रांट किया क्योंकि सरणियों का init संग्रह के लिए उपलब्ध नहीं था। धन्यवाद!
फीलोहो

15
हालांकि इसका उपयोग करने का एक पक्ष-प्रभाव है। अनाम वस्तुएं बनती हैं, जो हमेशा ठीक नहीं हो सकती हैं।
अमित

17
हालांकि इसे और अधिक देखने के बाद, मुझे कहना होगा कि मैं अजीब तरह से प्राकृतिक घोंसले के प्रति आकर्षित हूं, जो "गाली" संस्करण भी प्रदान करता है।
बिल के

4
हां - मुझे 'गाली' संस्करण काफी पसंद है, मुझे लगता है कि यह वास्तव में बहुत स्पष्ट और पठनीय है, लेकिन शायद यह सिर्फ मेरे लिए है।
बैरीफाइड

3
बिल्कुल सहमत हूँ, कोड के पदानुक्रम को गुई के पदानुक्रम को दर्शाते हुए विधि कॉल के अनुक्रम पर एक बड़ा सुधार है।
opsb

88

गतिशील परदे के पीछे (1.3 में जोड़ा गया) आपको रनटाइम पर एक नए प्रकार को परिभाषित करने की अनुमति देता है जो एक इंटरफ़ेस के अनुरूप है। यह समय की एक आश्चर्यजनक संख्या में काम आता है।


10
गतिशील प्रॉक्सी एक फू इंटरफेस लिखने और डिफ़ॉल्ट रूप से "FooImpl" वर्ग के साथ हर जगह उपयोग करने का एक बड़ा कारण है। यह पहली बार में बदसूरत लग सकता है ("क्यों न केवल एक वर्ग है जिसे फू कहा जाता है?") लेकिन भविष्य के लचीलेपन और इकाई परीक्षणों के लिए नकली क्षमता के मामले में लाभ आसान हैं। जबकि गैर-इंटरफेस के लिए भी इसे करने के तरीके हैं, उन्हें आमतौर पर cblib जैसे अतिरिक्त सामान की आवश्यकता होती है।
डारिएन

82

अंतिम आरंभ को स्थगित किया जा सकता है।

यह सुनिश्चित करता है कि तर्क रिटर्न मूल्यों के एक जटिल प्रवाह के साथ भी हमेशा सेट किया जाता है। किसी मामले को याद करना और दुर्घटना से अशक्त होना बहुत आसान है। यह वापसी को असंभव नहीं बनाता है, बस स्पष्ट है कि यह उद्देश्य पर है:

public Object getElementAt(int index) {
    final Object element;
    if (index == 0) {
         element = "Result 1";
    } else if (index == 1) {
         element = "Result 2";
    } else {
         element = "Result 3";
    }
    return element;
}

यह आश्चर्य की बात है। क्या कोई निष्पक्ष रूप से कह सकता है, "अंतिम चर का मान एक बार सेट किया जा सकता है", कोई फर्क नहीं पड़ता कि सेट कहां होता है?
डेविड कोएले

29
हां, लेकिन अधिक दृढ़ता से: "अंतिम चर का मूल्य एक बार निर्धारित किया जाना चाहिए"
एलन लालडे

6
+1 सहमत, यह संकलन समय पर त्रुटियों को पहचानने के लिए एक और मूल्यवान उपकरण है, और एक जिसे प्रोग्रामर किसी कारण से उपयोग करने में शर्म करते हैं। ध्यान दें कि जावा 5 के बाद से, 'फाइनल' में थ्रेड-सेफ्टी निहितार्थ भी हैं, क्योंकि कंस्ट्रक्टर के दौरान अंतिम वेरिएबल को सेट करना संभव है।
नील कॉफ़ी

4
हालांकि इस विशिष्ट विधि के लिए, मैं सिर्फ कई रिटर्न का उपयोग करूंगा। वास्तव में, ज्यादातर मामलों में जहां यह लागू होता है, मैं शायद इसे एक अलग विधि में बदल दूंगा और कई रिटर्न का उपयोग करूंगा।
ripper234

मुझे यह पसंद है! मैंने हमेशा अंतिम कीवर्ड हटा दिया क्योंकि मुझे लगा कि यह विफल हो जाएगा। धन्यवाद!
KARASZI इस्तवान

62

मुझे लगता है कि जावा की एक और "अनदेखी" सुविधा जेवीएम ही है। यह शायद सबसे अच्छा उपलब्ध VM है। और यह बहुत सी रोचक और उपयोगी भाषाओं (Jython, JRuby, Scala, Groovy) का समर्थन करता है। उन सभी भाषाओं को आसानी से और मूल सहयोग कर सकते हैं।

यदि आप एक नई भाषा डिज़ाइन करते हैं (जैसे कि स्कैला-केस में) तो आपके पास तुरंत सभी मौजूदा लाइब्रेरी उपलब्ध हैं और इसलिए आपकी भाषा शुरू से ही "उपयोगी" है।

वे सभी भाषाएँ हॉटस्पॉट अनुकूलन का उपयोग करती हैं। VM बहुत अच्छी तरह से मॉनिटर और डीबग करने योग्य है।


18
नहीं, यह वास्तव में बहुत अच्छा वीएम नहीं है। यह पूरी तरह से JAVA को चलाने के लिए डिज़ाइन किया गया था। ठेठ गतिशील और कार्यात्मक भाषाएँ इसके साथ अच्छी तरह से काम नहीं करती हैं। आप वीएम का उपयोग करना चाहते हैं। आपको .NET / मोनो का उपयोग करना चाहिए। जिसे हर भाषा के साथ काम करने के लिए डिज़ाइन किया गया था ...
Hades32

14
वास्तव में JVM पूरी तरह से जावा बाइटकोड को चलाने के लिए डिज़ाइन किया गया है। आप सबसे आधुनिक भाषाओं को जावा बाइटकोड में संकलित कर सकते हैं। जावा बाइटकोड में केवल एक चीज की कमी है, वह है गतिशील भाषा समर्थन, संकेत और पूंछ पुनरावृत्ति समर्थन।
15:50 बजे mcjabberz

12
@ Hades32: वास्तव में .NET VM JVM के समान है। इसे केवल हाल ही में गतिशील भाषाओं के लिए समर्थन मिला (DLR के साथ) और जावा 7 को भी उस समर्थन के रूप में प्राप्त होने वाला है। और .NET (C #, Visual Basic.NET, ...) की शास्त्रीय "हर भाषा" सभी में बहुत ही समान सुविधा सेट है।
जोकिम सॉउर

13
JVM जेनरिक का समर्थन नहीं करता है, जबकि .NET VM करता है। जेवीएम सबसे अच्छा कहीं नहीं है।
ब्लाइंडी

3
विशिष्ट भाषा सुविधाओं के बारे में शिकायतों को डिस्काउंट करने के लिए नहीं, सीधे जेवीएम द्वारा समर्थित नहीं ... लेकिन मुझे लगता है कि स्थिरता, क्रॉस-प्लेटफॉर्म स्थिरता, और अच्छे प्रदर्शन दूर हैं और कारणों से ऊपर जेवीएम को अतिरिक्त अंक मिलते हैं। मैं कई वर्षों से कई प्लेटफार्मों पर (एएस / 400 सहित) सर्वर-साइड जावा के साथ काम कर रहा हूं और बहुत अधिक पूरी तरह से इसके बारे में भूल गया हूं - कीड़े बहुत अधिक हमेशा कोड में होते हैं जिन्हें मैं ठीक कर सकता हूं, और यह बस दुर्घटना नहीं करता है।
रॉब व्हेलन

58

आप एक गुमनाम उपवर्ग को परिभाषित कर सकते हैं और सीधे उस पर एक विधि को कॉल कर सकते हैं भले ही वह कोई इंटरफेस लागू न करे।

new Object() {
  void foo(String s) {
    System.out.println(s);
  }
}.foo("Hello");

@Vuntic - यह आपको उस संदर्भ के भीतर एक साधारण वर्ग को परिभाषित करने की अनुमति देता है जिसकी उसे आवश्यकता है।
चोसपंडियन

1
@ चेताओ, लेकिन क्यों? एक वास्तविक उदाहरण मिला जहां यह उपयोगी है?
Thorbjørn रावन एंडरसन

10
@ राउटर - उस मामले में, जिस विधि को अनाम वस्तु पर बुलाया जाता है ( start()) वास्तव में उपवर्ग में परिभाषित नहीं है ...
एक्सल

वास्तव में, यह एक बहुत ही उपयोगी सुविधा है यदि आप एक बेस क्लास का विस्तार करते हैं जो कुछ आवश्यक सेटअप करता है, तो आपके द्वारा लिखे गए तरीके को कॉल करता है, और फिर फाड़ देता है। बेस क्लास में एक विधि को कॉल करके चीज़ को बंद करें (जो मैं संभवतः एक ही नाम नहीं दूंगा)। यहां एक उदाहरण उपयोग (परिभाषा नहीं) है
AmigoNico

56

AsList में विधि java.util.Arraysvarargs, सामान्य तरीके और autoboxing का एक अच्छा संयोजन की अनुमति देता है:

List<Integer> ints = Arrays.asList(1,2,3);

15
आप एक सूची निर्माणकर्ता के साथ लौटी हुई सूची को लपेटना चाहते हैं अन्यथा स्याही को निश्चित आकार दिया जाएगा (क्योंकि यह सरणी द्वारा समर्थित है)
KitsuneYMG

2
Arrays.asListआप कर सकते हैं कि असामान्य विशेषता है set()तत्व नहीं बल्कि add()या remove()। इसलिए मैं आमतौर पर इसे एक new ArrayList(...)या एक में लपेटता हूं Collections.unmodifiableList(...), इस पर निर्भर करता है कि मैं सूची को संशोधित करना चाहता हूं या नहीं।
क्रिश्चियन सेमरू

53

इस कीवर्ड का उपयोग खेतों / आंतरिक कक्षा से युक्त कक्षा के तरीकों तक पहुँचने के लिए। नीचे दिए गए, बल्कि उदाहरण के लिए, हम गुमनाम आंतरिक वर्ग से कंटेनर श्रेणी के सॉर्टिंग फ़ील्ड का उपयोग करना चाहते हैं। इस के बजाय कंटेनरक्लास.थिस.सोर्टअस्सकेडिंग का उपयोग करना। सार्टकॉन्डिंग ट्रिक करता है।

import java.util.Comparator;

public class ContainerClass {
boolean sortAscending;
public Comparator createComparator(final boolean sortAscending){
    Comparator comparator = new Comparator<Integer>() {

        public int compare(Integer o1, Integer o2) {
            if (sortAscending || ContainerClass.this.sortAscending) {
                return o1 - o2;
            } else {
                return o2 - o1;
            }
        }

    };
    return comparator;
}
}

4
केवल तभी आवश्यक है जब आपने नाम (आपके मामले में, विधि पैरामीटर नाम के साथ) छायांकित किया हो। यदि आपने तर्क को कुछ और कहा है, तो आप 'इस' का उपयोग किए बिना सीधे कंटेनर वर्ग के सॉर्ट करें सदस्य चर तक पहुंच सकते हैं।
स्के।

7
यह अभी भी संलग्न वर्ग के संदर्भ के लिए उपयोगी है, उदाहरण के लिए। यदि आपको इसे किसी विधि या कसौटी पर पारित करने की आवश्यकता है।
फीलो

एंड्रॉइड लेआउट विकास में अक्सर उपयोग किया जाता है, एक बटन के श्रोता, से, संदर्भ, प्राप्त करने के लिए MyActivity.this
espinchi

52

वास्तव में एक विशेषता नहीं है, लेकिन एक मनोरंजक ट्रिक जिसे मैंने हाल ही में कुछ वेब पेज में खोजा है:

class Example
{
  public static void main(String[] args)
  {
    System.out.println("Hello World!");
    http://Phi.Lho.free.fr

    System.exit(0);
  }
}

एक वैध जावा प्रोग्राम है (हालाँकि यह एक चेतावनी उत्पन्न करता है)। यदि आप क्यों नहीं देखते हैं, तो ग्रेगरी का जवाब देखें! ;-) अच्छा, यहाँ वाक्यविन्यास भी एक संकेत देता है!


15
नीट, एक टिप्पणी के साथ एक लेबल :)
थोरबजर्न रेवन एंडरसन

46

यह बिल्कुल "छिपी हुई विशेषताएं" नहीं है और बहुत उपयोगी नहीं है, लेकिन कुछ मामलों में बेहद दिलचस्प हो सकती है:
कक्षा sun.misc.Unsafe - आपको जावा में प्रत्यक्ष मेमोरी प्रबंधन को लागू करने की अनुमति देगा (आप यहां तक ​​कि स्वयं-संशोधित जावा कोड भी लिख सकते हैं) यदि आप बहुत प्रयास करते हैं):

public class UnsafeUtil {

    public static Unsafe unsafe;
    private static long fieldOffset;
    private static UnsafeUtil instance = new UnsafeUtil();

    private Object obj;

    static {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);

            unsafe = (Unsafe)f.get(null);
            fieldOffset = unsafe.objectFieldOffset(UnsafeUtil.class.getDeclaredField("obj"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };
}

20
यह एक सूरज है। * एपीआई जो वास्तव में जावा भाषा के प्रति se
DW

Unsafe पर कई अन्य जिज्ञासु विधियाँ हैं जैसे कि किसी रचनाकार को बुलाए बिना कोई वस्तु बनाना, Malloc / realloc / वास्तविक शैली के तरीके।
पीटर लॉरी

मुझे एस्प्रिटली प्राइमर मिलता है और मेमोरी स्थानों पर बसता है, जैसे डड डबल (लंबा पता, डबल डी)।
डैनियल

42

जब की तरह छिपा घुमाओ मैं में काम कर Ctrl- Shift- F1सुविधा।

यह वर्तमान विंडो के घटक पेड़ को डंप करता है।
(मान लें कि आपने उस कीस्ट्रोक को किसी और चीज़ से नहीं बांधा है।)


1
सबसे अधिक संभावना है कि आपके विंडो प्रबंधक के पास उस कुंजी के लिए बाध्य है। सूक्ति इसे बांधती नहीं है, इसलिए मैं मान रहा हूं कि आप केडीई चला रहे हैं जो इसे 'डेस्कटॉप 13 पर स्विच' करने के लिए बांधता है। आप इसे कंट्रोल पैनल, रीजनल, कीबोर्ड शॉर्टकट में जाकर
शिफ्ट-

40

प्रत्येक वर्ग फ़ाइल हेक्स मान 0xCAFEBABE से शुरू होती है ताकि इसे मान्य JVM बायटेकोड के रूप में पहचाना जा सके।

( स्पष्टीकरण )


38

मेरा वोट java.util.concurrent में अपने समवर्ती संग्रहों और लचीले निष्पादकों के साथ अन्य थ्रेड पूल, अनुसूचित कार्यों और समन्वित कार्यों की अनुमति देता है। DelayQueue मेरा व्यक्तिगत पसंदीदा है, जहां तत्वों को एक निर्दिष्ट देरी के बाद उपलब्ध कराया जाता है।

java.util.Timer और TimerTask को सुरक्षित रूप से आराम करने के लिए रखा जा सकता है।

इसके अलावा, बिल्कुल छिपा नहीं है, लेकिन तारीख और समय से संबंधित अन्य वर्गों से एक अलग पैकेज में। java.util.concurrent.TimeUnit नैनोसेकंड, माइक्रोसेकंड, मिलीसेकंड और सेकंड के बीच कनवर्ट करते समय उपयोगी है।

यह सामान्य से कुछ बेहतर पढ़ता है कुछValue * 1000 या someValue / 1000।


हाल ही में खोजा गया CountDownLatchऔर CyclicBarrier- इतना उपयोगी!
राफेल

37

भाषा-स्तर का कीवर्ड।


19
मुखर के साथ परेशानी यह है कि इसे रनटाइम के दौरान स्विच करने की आवश्यकता है।
extraneon

10
लेकिन अगर यह अक्षम है तो ऐसा लगता है कि यह वहां नहीं है। आप अपने कोड में जितने चाहें उतने जोड़ सकते हैं और यदि वे अक्षम हैं तो आपके पास कोई प्रदर्शन जुर्माना नहीं होगा।
रवि वलाऊ

5
मुझे विश्वास है कि मुखर के बारे में यह एक अच्छी बात है: इसे दंड के बिना बंद किया जा सकता है।
और।

समस्या यह है, अगर आपने गलती से एक मुखर में साइड इफेक्ट लागू किया है, तो आपको उर प्रोग्राम को काम करने के लिए जोर लगाना होगा ...
Chii

यह पता लगाने के लिए कि क्या आरोही चालू है, आप {बूलियन एसेरटॉन्से = गलत का उपयोग कर सकते हैं; assert assertsOn = true; if (assertsOn) {/ * जटिल सत्यापन * /}}। यह भी लॉग इन या अपवाद फेंकने की अनुमति देता है अगर मुखर राज्य अपेक्षित नहीं है।
fernacolo

37

वास्तव में जावा भाषा का हिस्सा नहीं है, लेकिन सूर्य के जेडीके के साथ आने वाला जावप डिस्सेम्बलर व्यापक रूप से ज्ञात या उपयोग नहीं किया गया है।


36

1.5 में प्रत्येक लूप के निर्माण के अलावा। मैं <3 यह।

// For each Object, instantiated as foo, in myCollection
for(Object foo: myCollection) {
  System.out.println(foo.toString());
}

और नेस्टेड उदाहरणों में इस्तेमाल किया जा सकता है:

for (Suit suit : suits)
  for (Rank rank : ranks)
    sortedDeck.add(new Card(suit, rank));

प्रत्येक निर्माण के लिए सरणियों पर भी लागू होता है, जहां यह सूचक के बजाय सूचकांक चर को छुपाता है। निम्नलिखित विधि एक अंतर में मानों का योग लौटाती है:

// Returns the sum of the elements of a
int sum(int[] a) {
  int result = 0;
  for (int i : a)
    result += i;
  return result;
}

सूर्य प्रलेखन के लिए लिंक


30
मुझे लगता है कि iयहां उपयोग करना अति-भ्रमित करने वाला है, क्योंकि ज्यादातर लोग उम्मीद करते हैं कि मैं एक सूचकांक हूं और सरणी तत्व नहीं।
cdmckay

तो ... int sum (int [] array) {int result = 0; for (int element: array) {result + = तत्व; } वापसी परिणाम; }
ड्रू

28
केवल एक चीज जो मुझे इस बारे में पागल करती है, वह यह है कि ऐसा लगता है कि लूप काउंट वैल्यू तक पहुंचने के लिए एक कीवर्ड बनाना वास्तव में बहुत आसान होगा, लेकिन आप नहीं कर सकते। अगर मैं दो सरणियों पर लूप करना चाहता हूं और पहले में मूल्यों के आधार पर एक दूसरे में परिवर्तन कर रहा हूं, तो मुझे पुराने सिंटैक्स का उपयोग करने के लिए मजबूर किया जाता है क्योंकि मेरे पास दूसरे सरणी में कोई ऑफसेट नहीं है।
झेरिको

6
यह शर्म की बात है कि यह एन्यूमरेशंस के साथ भी काम नहीं करता है, जैसे कि जेएनडीआई में उपयोग किया जाता है। यह वहाँ पुनरावृत्तियों के लिए है।
extraneon

3
@extraneon: Collections.list (गणना <T> e) पर एक नज़र डालें। कि फोर्क लूप में एन्यूमरेटिंग एन्यूमरेशन के साथ मदद करनी चाहिए।
वर्नर लेहमन

34

मैंने व्यक्तिगत रूप से java.lang.Voidबहुत देर से खोजा - जेनेरिक के साथ संयोजन के रूप में कोड पठनीयता में सुधार करता है, जैसेCallable<Void>


2
काफी नहीं। कुछ बिंदु पर, आपको विशिष्ट होने की आवश्यकता है: Executors.newSingleThreadExecutor (।) सबमिट करें (नया कॉल करने योग्य <शून्य> () {..}) - आप एक नया कॉल करने योग्य <?> () का संकेत नहीं दे सकते, आपको निर्दिष्ट करने की आवश्यकता है? एक स्पष्ट प्रकार - इस प्रकार, यह Callable <Object> का एक विकल्प है।
रहल ल्युथि

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