क्या जावा का उपयोग करने वाला कथन है?


107

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

C # में यह कुछ इस तरह है:

using (var session = new Session())
{


}

तो वस्तु दायरे से बाहर हो जाती है और अपने आप बंद हो जाती है।


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

4
@Joren आपकी टिप्पणी पर मतदान हो रहा है लेकिन मैं थोड़ी और जानकारी के साथ कर सकता हूं। आप "जीवनकाल" विचार का परिचय देने वाले व्यक्ति हैं तो आप कहते हैं कि यह "जीवनकाल" के बारे में नहीं है। स्कोप एमएसडीएन लाइब्रेरी से परिभाषा में उपयोग किया जाने वाला शब्द है, शायद मैंने इसका दुरुपयोग किया है। आप कैसे परिभाषित करेंगे using statement?
जाला

1
स्कोप कोड में उस क्षेत्र को संदर्भित करता है जिसमें आप किसी पहचानकर्ता को उसके पूर्ण योग्य नाम (स्थानीय चर, प्रकार, विधि का नाम और ऐसे) का उपयोग किए बिना संदर्भित कर सकते हैं। आजीवन उस समय को संदर्भित करता है जिसमें कोई वस्तु या चर सुलभ होता है। ब्लॉगs.msdn.com/b/ericlippert/archive/2009/08/03/… पर
Joren

2
उदाहरण के लिए, यदि आपके पास एक स्थानीय वैरिएबल है और इसके लिए एक वैल्यू टाइप इंस्टेंस प्रदान करता है, तो आपके वैरिएबल का जीवनकाल समाप्त होने पर आपके जीवनकाल का अंत हो जाएगा। लेकिन अगर आपने एक ऑब्जेक्ट आवंटित किया है, और एक संदर्भ को स्थानीय में संग्रहीत किया है, तो उस वस्तु का जीवनकाल बहुत अच्छी तरह से उसके भंडारण के जीवनकाल का विस्तार कर सकता है, जब तक कि अभी भी ऑब्जेक्ट का संदर्भ कहीं और है। के रूप में using, यह स्वचालित रूप से अपने दायरे के अंत में वस्तु का निपटान करता है, लेकिन यह वस्तु को नष्ट नहीं करता है - इसका जीवनकाल तब तक खत्म नहीं होता है जब तक कि इसके सभी संदर्भ गायब नहीं हो जाते।
जोरेन

जवाबों:


124

जावा 7 ने ऑटोमैटिक रिसोर्स ब्लॉक मैनेजमेंट की शुरुआत की जो इस फीचर को जावा प्लेटफॉर्म पर लाता है। जावा के पूर्व संस्करणों में कुछ भी समानता नहीं थी using

एक उदाहरण के रूप में, आप java.lang.AutoCloseableनिम्नलिखित तरीके से किसी भी चर का उपयोग कर सकते हैं :

try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
    ...
}

जावा का java.io.Closeableइंटरफ़ेस, धाराओं द्वारा कार्यान्वित, स्वचालित रूप से विस्तारित होता है AutoCloseable, इसलिए आप पहले tryसे ही एक ब्लॉक में धाराओं का उपयोग कर सकते हैं उसी तरह से आप उन्हें सी # usingब्लॉक में उपयोग करेंगे । यह C # के समतुल्य है using

संस्करण 5.0 केAutoCloseable रूप में , हाइबरनेट सत्र लागू होते हैं और एआरएम ब्लॉकों में ऑटो-बंद हो सकते हैं। हाइबरनेट सत्र केAutoCloseable पिछले संस्करणों में लागू नहीं किया गया था । तो आपको इस सुविधा का उपयोग करने के लिए हाइबरनेट> = 5.0 पर होना होगा।


1
जावा 7 के साथ "सौभाग्य से" अब उपलब्ध है, यह उत्तर अब सच नहीं है (और मुझे लगता है कि एआरएम ब्लॉक वास्तव में क्या usingकरता है)।
जोकिम सॉयर

@ जोकिम सौर: धन्यवाद। मैंने समय बीतने को प्रतिबिंबित करने के लिए अपना जवाब अपडेट किया। एआरएम ब्लॉकों के आपके बिंदु पर वास्तव में क्या उपयोग करता है; जिस समय मैंने यह उत्तर लिखा था, यह मुझे ऐसा लग रहा था जैसे एआरएम ब्लॉक को ब्लॉक करने की कोशिश करनी थी, जबकि उपयोग करना किसी भी मनमाने ब्लॉक पर लागू किया जा सकता है। इसे देखते हुए, ऐसा लगता है कि इसे पूरा करने के लिए जावा में डू कीवर्ड का उपयोग किया जा सकता है। क्या हाल ही में इस प्रस्ताव में जोड़ा गया था या मैंने इसे पहली बार याद किया था? साथ ही ओपी ने विशेष रूप से हाइबरनेट सत्रों के बारे में पूछा। AFAIK: हाइबरनेट सत्र अभी भी लागू AutoCloseableनहीं होते हैं इसलिए वे अभी तक एआरएम का उपयोग नहीं कर सकते हैं।
असफ

1
4.3 सीतनिद्रा में होना घटना नहीं AutoCloseable लागू नहीं है। docs.jboss.org/hibernate/orm/4.3/javadocs/index.html?org/… मुझे लगता है कि यह हर किसी के लिए है कि वह अपना रैपर लिखे?
आंद्रेई रोनेया

1
सत्र AutoCloseable को Session.close के रूप में लागू नहीं कर सकता () एक कनेक्शन देता है। मुझे लगता है कि यह एक खराब डिजाइन है लेकिन मुझे संदेह है कि यह कभी भी बदल जाएगा।
usr-local-ΕΨΗΕΛΩΝ

@ usr-local-ured मुझे लगा कि वे हाइबरनेट का उपयोग करने के लिए किसी को बाध्य कर रहे हैं, अगर वह उस इंटरफ़ेस को लागू करने के लिए java 7 में स्विच कर सकता है। AutoCloseableजावा 7 से पहले मौजूद नहीं था?
नील

31

जावा 7 से पहले , वहाँ था कोई जावा में ऐसी सुविधा (जावा 7 और ऊपर देख असफ़ के जवाब के बारे में एआरएम )।

आपको इसे मैन्युअल रूप से करने की आवश्यकता है और यह एक दर्द था :

AwesomeClass hooray = null;
try {
  hooray = new AwesomeClass();
  // Great code
} finally {
  if (hooray!=null) {
    hooray.close();
  }
}

और यह बस एक कोड जब न तो है // Great codeऔर न ही hooray.close()किसी भी अपवाद फेंक कर सकते हैं।

यदि आप वास्तव में केवल एक चर के दायरे को सीमित करना चाहते हैं, तो एक साधारण कोड ब्लॉक काम करता है:

{
  AwesomeClass hooray = new AwesomeClass();
  // Great code
}

लेकिन इसका मतलब शायद यह नहीं है।


1
यदि // Great codeअपवाद फेंकता है तो आपके जावा समतुल्य कोई समस्या नहीं होनी चाहिए ।
चेसो

3
जब कंस्ट्रक्टर एक अपवाद फेंकता है, तो मुझे लगता है कि आपका कोड NullPointerException में परिणाम करने वाला है जो मूल अपवाद को मास्क करता है।
माइकल बोर्गवर्ड

@ माइकल: वास्तव में मेरा उदाहरण संकलित नहीं होगा, क्योंकि horrayउस बिंदु पर (अभी तय नहीं) शुरू हो सकता है।
जोकिम सॉयर

4
फ्लोटिंग सिंपल ब्लॉक्स के लिए +1 गुंजाइश को सीमित करने में सक्षम है। हालाँकि, जब भी मैं इन्हें देखता हूँ तो यह लगभग हमेशा एक संकेतक होता है कि इस विधि को छोटे टुकड़ों में तोड़ दिया जाए।
मार्क पीटर्स

1
यदि आप कंस्ट्रक्टर से किसी भी अपवाद को पकड़ना चाहते हैं, तो आपको इसे कोशिश ब्लॉक के अंदर रखना होगा। एक और कोशिश / पकड़ में पूरी बात लपेटना बोझिल होगा।
ths

19

जावा 7 के बाद से यह करता है: http://blogs.oracle.com/darcy/entry/project_coin_updated_n_ecec

प्रश्न में कोड के लिए सिंटैक्स होगा:

try (Session session = new Session())
{
  // do stuff
}

ध्यान दें कि इसके (कई) उप-इंटरफेस Sessionको लागू करने AutoClosableया करने की आवश्यकता है ।


8

तकनीकी तौर पर:

DisposableObject d = null;
try {
    d = new DisposableObject(); 
}
finally {
    if (d != null) {
        d.Dispose();
    }
}

2
इसे करने का सबसे अच्छा तरीका नहीं है। stackoverflow.com/questions/1909662/…
मार्क बायर्स

5
यह अनिवार्य रूप से समकक्ष होगा। मुझे परवाह नहीं है अगर यह सबसे अच्छा तरीका है।
चोसपंडियन

2
एक सच्चे C # प्रोग्रामर की तरह लिखा गया। ;)
नील




2

यदि आप संसाधन प्रबंधन में रुचि रखते हैं, तो प्रोजेक्ट लोम्बोक@Cleanup एनोटेशन प्रदान करता है । सीधे उनकी साइट से लिया गया:

आप @Cleanupकिसी दिए गए संसाधन को सुनिश्चित करने के लिए उपयोग कर सकते हैं कि कोड निष्पादन पथ आपके वर्तमान दायरे से बाहर निकलने से पहले स्वचालित रूप से साफ हो जाए। आप किसी भी स्थानीय चर घोषणा को @Cleanup एनोटेशन के साथ एनोटेट करके ऐसा करते हैं:

@Cleanup InputStream in = new FileInputStream("some/file");

परिणामस्वरूप, आप जिस दायरे में हैं, उसके अंत में in.close()कहा जाता है। यह कॉल एक कोशिश / अंत में निर्माण के माध्यम से चलाने की गारंटी है। नीचे दिए गए उदाहरण को देखें कि यह कैसे काम करता है।

यदि आप जिस प्रकार की वस्तु को साफ़ करना चाहते हैं, उसमें कोई close() विधि नहीं है , लेकिन कोई अन्य नो-तर्क पद्धति है, तो आप इस विधि का नाम इस तरह निर्दिष्ट कर सकते हैं:

@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);

डिफ़ॉल्ट रूप से, क्लीनअप विधि होना माना जाता है close()। एक सफाई विधि है कि तर्क लेता के माध्यम से नहीं कहा जा सकता @Cleanup

वेनिला जावा

import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }
}

लोम्बोक के साथ

import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}


1

कृपया जावा कीवर्ड की इस सूची को देखें ।

  1. usingकीवर्ड दुर्भाग्य से सूची का हिस्सा नहीं है।
  2. और usingजावा में अब तक किसी भी अन्य कीवर्ड के माध्यम से सी # कीवर्ड की कोई समानता नहीं है ।

इस तरह के "using"व्यवहार की नकल करने के लिए , आपको एक try...catch...finallyब्लॉक का उपयोग करना होगा, जहां आप संसाधनों का निपटान करेंगे finally


6
तथ्य यह usingहै कि एक खोजशब्द नहीं है एक बात का मतलब नहीं है। एक ही सुविधा एक और कीवर्ड के साथ लागू की जा सकती है (और होगी!), जैसा कि @BalusC ने उल्लेख किया है।
जोआचिम सॉर

1
मैं सहमत हूँ! लेकिन अभी के लिए, यह मौजूद नहीं है, है ना? यही ओपी ने पूछा, अगर अभी कुछ समान था। यह जानना अच्छा है कि यह भविष्य के रिलीज में मौजूद होगा, लेकिन यह एक चीज़ को अब, एक या दूसरे तरीके से नहीं बदलता है। वैसे भी, @BalusC द्वारा दी गई जानकारी हालांकि बहुत अच्छी है! =)
विल मार्कॉइलर

2
मैं इससे सहमत हूं, लेकिन आपकी पोस्ट यह कहती दिख रही है कि जो तथ्य usingजावा कीवर्ड की सूची में नहीं है, इसका मतलब है कि यह सुविधा जावा भाषा में मौजूद नहीं है। और यह सच नहीं है।
जोकिम सॉयर

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

मैंने अपने उत्तर को यह निर्दिष्ट करते हुए संपादित किया कि कोई usingकीवर्ड नहीं था , और न ही अब के लिए कोई समानता। धन्यवाद @ जोशिम सौअर! =)
विल मार्क्युइलर


0

चर को स्वचालित रूप से बंद / निपटाने के बारे में बात करने के बजाय, एक चर के दायरे को सीमित करने के बारे में सवाल का जवाब देने के लिए।

जावा में आप घुंघराले कोष्ठक का उपयोग करके बंद, गुमनाम स्कोप को परिभाषित कर सकते हैं। यह बेहद सरल है।

{
   AwesomeClass hooray = new AwesomeClass()
   // Great code
}

चर hoorayकेवल इस दायरे में उपलब्ध है, और इसके बाहर नहीं।

यह उपयोगी हो सकता है यदि आपके पास दोहराए गए चर हैं जो केवल अस्थायी हैं।

उदाहरण के लिए, प्रत्येक सूचकांक के साथ। जैसे itemलूप के लिए वैरिएबल को बंद किया जाता है (यानी, केवल इसके अंदर उपलब्ध है), indexवैरिएबल को स्कोप गुमनाम दायरे में बंद किया जाता है।

// first loop
{
    Integer index = -1;
    for (Object item : things) {index += 1;
        // ... item, index
    }
}

// second loop
{
    Integer index = -1;
    for (Object item : stuff) {index += 1;
        // ... item, index
    }
}

मैं भी इसका उपयोग कभी-कभी करता हूं यदि आपके पास वैरिएबल स्कोप प्रदान करने के लिए लूप नहीं है, लेकिन आप जेनेरिक वैरिएबल नामों का उपयोग करना चाहते हैं।

{
    User user = new User();
    user.setId(0);
    user.setName("Andy Green");
    user.setEmail("andygreen@gmail.com");
    users.add(user);
}

{
    User user = new User();
    user.setId(1);
    user.setName("Rachel Blue");
    user.setEmail("rachelblue@gmail.com");
    users.add(user);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.