CodeGym/Java Blog/अनियमित/एओपी क्या है? पहलू-उन्मुख प्रोग्रामिंग के सिद्धांत
John Squirrels
स्तर 41
San Francisco

एओपी क्या है? पहलू-उन्मुख प्रोग्रामिंग के सिद्धांत

अनियमित ग्रुप में प्रकाशित
सदस्य
हाय दोस्तों और लड़कियों! बुनियादी अवधारणाओं को समझे बिना, कार्यक्षमता के निर्माण के लिए रूपरेखा और दृष्टिकोण में तल्लीन करना काफी कठिन है। तो आज हम ऐसे ही एक कॉन्सेप्ट के बारे में बात करेंगे- AOP, जिसे आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग भी कहा जाता है । एओपी क्या है?  आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग के सिद्धांत - 1यह विषय आसान नहीं है और शायद ही कभी सीधे उपयोग किया जाता है, लेकिन कई ढांचे और प्रौद्योगिकियां हुड के तहत इसका उपयोग करती हैं। और निश्चित रूप से, कभी-कभी साक्षात्कार के दौरान, आपको सामान्य शब्दों में वर्णन करने के लिए कहा जा सकता है कि यह किस प्रकार का जानवर है और इसे कहाँ लागू किया जा सकता है। तो आइए बुनियादी अवधारणाओं और जावा में AOP के कुछ सरल उदाहरणों पर एक नजर डालते हैं । अब तो, AOP पहलू-उन्मुख प्रोग्रामिंग के लिए खड़ा है, जो क्रॉस-कटिंग चिंताओं को अलग करके एक अनुप्रयोग के विभिन्न भागों की प्रतिरूपकता को बढ़ाने के उद्देश्य से एक प्रतिमान है। इसे पूरा करने के लिए, मूल कोड में बदलाव किए बिना मौजूदा कोड में अतिरिक्त व्यवहार जोड़ा जाता है। दूसरे शब्दों में, हम इसे संशोधित कोड में बदलाव किए बिना विधियों और कक्षाओं के शीर्ष पर अतिरिक्त कार्यक्षमता लटकाने के बारे में सोच सकते हैं। यह क्यों आवश्यक है? जल्दी या बाद में, हम निष्कर्ष निकालते हैं कि विशिष्ट वस्तु-उन्मुख दृष्टिकोण हमेशा कुछ समस्याओं को प्रभावी ढंग से हल नहीं कर सकता है। और जब वह पल आता है, AOP बचाव के लिए आता है और हमें एप्लिकेशन बनाने के लिए अतिरिक्त टूल देता है। और अतिरिक्त टूल का अर्थ है सॉफ़्टवेयर विकास में अधिक लचीलापन, जिसका अर्थ है किसी विशेष समस्या को हल करने के लिए अधिक विकल्प।

एओपी लागू करना

आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग को क्रॉस-कटिंग कार्यों को करने के लिए डिज़ाइन किया गया है, जो कि कोई भी कोड हो सकता है जिसे विभिन्न तरीकों से कई बार दोहराया जा सकता है, जिसे पूरी तरह से एक अलग मॉड्यूल में संरचित नहीं किया जा सकता है। तदनुसार, एओपी हमें इसे मुख्य कोड के बाहर रखने देता है और इसे लंबवत रूप से घोषित करता है। एक उदाहरण किसी एप्लिकेशन में सुरक्षा नीति का उपयोग कर रहा है। विशिष्ट रूप से, सुरक्षा किसी अनुप्रयोग के कई तत्वों से चलती है। क्या अधिक है, एप्लिकेशन की सुरक्षा नीति को एप्लिकेशन के सभी मौजूदा और नए भागों पर समान रूप से लागू किया जाना चाहिए। उसी समय, उपयोग में आने वाली सुरक्षा नीति स्वयं विकसित हो सकती है। एओपी का उपयोग करने के लिए यह सही जगह है । साथ ही, एक अन्य उदाहरण लॉगिंग है. मैन्युअल रूप से लॉगिंग कार्यात्मक जोड़ने के बजाय लॉगिंग के लिए एओपी दृष्टिकोण का उपयोग करने के कई फायदे हैं:
  1. लॉगिंग के लिए कोड को जोड़ना और हटाना आसान है: आपको बस इतना करना है कि किसी पहलू के कुछ कॉन्फ़िगरेशन को जोड़ना या हटाना है।

  2. लॉगिंग के लिए सभी स्रोत कोड एक ही स्थान पर रखे जाते हैं, इसलिए आपको उन सभी स्थानों पर मैन्युअल रूप से खोज करने की आवश्यकता नहीं है जहां इसका उपयोग किया जाता है।

  3. लॉगिंग कोड कहीं भी जोड़ा जा सकता है, चाहे विधियों और कक्षाओं में जो पहले ही लिखे जा चुके हैं या नई कार्यक्षमता में। यह कोडिंग त्रुटियों की संख्या को कम करता है।

    साथ ही, डिज़ाइन कॉन्फ़िगरेशन से एक पहलू को हटाते समय, आप सुनिश्चित हो सकते हैं कि सभी ट्रेसिंग कोड चले गए हैं और कुछ भी छूटा नहीं है।

  4. पहलू अलग कोड हैं जिन्हें बार-बार सुधारा और उपयोग किया जा सकता है।
एओपी क्या है?  आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग के सिद्धांत - 2एओपी का उपयोग अपवाद हैंडलिंग, कैशिंग और इसे पुन: प्रयोज्य बनाने के लिए कुछ कार्यक्षमता निकालने के लिए भी किया जाता है।

AOP के मूल सिद्धांत

इस विषय में आगे बढ़ने के लिए, आइए पहले AOP की मुख्य अवधारणाओं को जानें। सलाह - अतिरिक्त तर्क या कोड को एक जॉइन पॉइंट से कॉल किया जाता है। किसी ज्वाइन पॉइंट के पहले, बाद में या इसके बजाय सलाह दी जा सकती है (नीचे उनके बारे में अधिक)। संभावित प्रकार की सलाह :
  1. पहले - इस प्रकार की सलाह को लक्ष्य विधियों से पहले लॉन्च किया जाता है, यानी जुड़ने वाले बिंदुओं को निष्पादित किया जाता है। कक्षाओं के रूप में पहलुओं का उपयोग करते समय, हम @Before एनोटेशन का उपयोग सलाह को पहले आने के रूप में चिह्नित करने के लिए करते हैं। .aj फ़ाइलों के रूप में पहलुओं का उपयोग करते समय , यह पहले () विधि होगी ।

  2. के बाद - सलाह जो विधियों के निष्पादन के बाद निष्पादित की जाती है (बिंदुओं में शामिल हों) पूरी हो जाती है, दोनों सामान्य निष्पादन के साथ-साथ अपवाद फेंकते समय भी।

    कक्षाओं के रूप में पहलुओं का उपयोग करते समय, हम @After एनोटेशन का उपयोग यह इंगित करने के लिए कर सकते हैं कि यह सलाह है जो बाद में आती है।

    एजे फाइलों के रूप में पहलुओं का उपयोग करते समय , यह बाद () विधि है।

  3. रिटर्निंग के बाद - यह सलाह केवल तभी की जाती है जब लक्ष्य विधि त्रुटियों के बिना सामान्य रूप से समाप्त हो जाती है।

    जब पहलुओं को कक्षाओं के रूप में दर्शाया जाता है, तो हम सफल समापन के बाद सलाह को क्रियान्वित करने के रूप में चिह्नित करने के लिए @AfterReturning एनोटेशन का उपयोग कर सकते हैं।

    .aj फ़ाइलों के रूप में पहलुओं का उपयोग करते समय , यह आफ्टर() रिटर्निंग (ऑब्जेक्ट ओब्ज) विधि होगी ।

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

    वर्ग पहलुओं के लिए, @AfterThrowing एनोटेशन का उपयोग यह इंगित करने के लिए किया जाता है कि अपवाद फेंकने के बाद इस सलाह का उपयोग किया जाता है।

    एजे फाइलों के रूप में पहलुओं का उपयोग करते समय , यह बाद () फेंकने (अपवाद ई) विधि होगी ।

  5. चारों ओर - शायद सबसे महत्वपूर्ण प्रकार की सलाह में से एक। यह एक विधि को घेरता है, अर्थात, एक जुड़ने वाला बिंदु जिसका हम उपयोग कर सकते हैं, उदाहरण के लिए, यह चुनने के लिए कि किसी दिए गए जुड़ाव बिंदु विधि को निष्पादित करना है या नहीं।

    आप सलाह कोड लिख सकते हैं जो ज्वाइन पॉइंट मेथड के निष्पादित होने से पहले और बाद में चलता है।

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

    वर्गों के रूप में दिए गए पहलुओं को देखते हुए, हम सलाह देने के लिए @Around एनोटेशन का उपयोग करते हैं जो एक जॉइन पॉइंट को लपेटता है। .aj फ़ाइलों के रूप में पहलुओं का उपयोग करते समय , यह विधि चारों ओर () विधि होगी ।

जॉइन प्वाइंट — चल रहे प्रोग्राम में वह बिंदु (अर्थात् मेथड कॉल, ऑब्जेक्ट क्रिएशन, वेरिएबल एक्सेस) जहां सलाह लागू की जानी चाहिए। दूसरे शब्दों में, यह एक प्रकार की नियमित अभिव्यक्ति है जिसका उपयोग कोड इंजेक्शन के लिए स्थान खोजने के लिए किया जाता है (ऐसे स्थान जहाँ सलाह लागू की जानी चाहिए)। पॉइंटकट - जुड़ने वाले बिंदुओं का एक सेट । एक पॉइंटकट यह निर्धारित करता है कि दी गई सलाह किसी दिए गए ज्वाइन पॉइंट पर लागू होती है या नहीं। पहलू - एक मॉड्यूल या वर्ग जो क्रॉस-कटिंग कार्यक्षमता को लागू करता है। आस्पेक्ट कुछ पॉइंटकट द्वारा परिभाषित ज्वाइन पॉइंट्स पर सलाह लागू करके शेष कोड के व्यवहार को बदल देता है । दूसरे शब्दों में, यह सलाह और जुड़ने के बिंदुओं का एक संयोजन है। परिचय- विदेशी कोड में पहलू की कार्यक्षमता जोड़ने के लिए एक वर्ग की संरचना को बदलना और/या वंशानुक्रम पदानुक्रम को बदलना। लक्ष्य - वह वस्तु जिस पर सलाह लागू की जाएगी। बुनाई - सलाहित प्रॉक्सी ऑब्जेक्ट बनाने के लिए पहलुओं को अन्य ऑब्जेक्ट्स से जोड़ने की प्रक्रिया। यह संकलन समय, लोड समय या रन टाइम पर किया जा सकता है। बुनाई तीन प्रकार की होती है:
  • संकलन-समय की बुनाई - यदि आपके पास पहलू का स्रोत कोड और कोड है जहां आप पहलू का उपयोग करते हैं, तो आप स्रोत कोड और पहलू को सीधे AspectJ संकलक का उपयोग करके संकलित कर सकते हैं;

  • संकलन के बाद की बुनाई (बाइनरी बुनाई) - यदि आप कोड में पहलुओं को बुनने के लिए स्रोत कोड परिवर्तनों का उपयोग नहीं कर सकते हैं या नहीं करना चाहते हैं, तो आप पहले से संकलित कक्षाएं या जार फाइलें ले सकते हैं और उनमें पहलुओं को इंजेक्ट कर सकते हैं;

  • लोड-टाइम बुनाई - यह केवल बाइनरी बुनाई है जो तब तक विलंबित होती है जब तक कि क्लास लोडर क्लास फाइल को लोड नहीं करता है और जेवीएम के लिए क्लास को परिभाषित करता है।

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

AspectJ - AOP प्रतिमान का एक विशिष्ट कार्यान्वयन जो क्रॉस-कटिंग कार्यों को करने की क्षमता को लागू करता है। दस्तावेज यहां पाया जा सकता है ।

जावा में उदाहरण

अगला, AOP की बेहतर समझ के लिए , हम छोटे "हैलो वर्ल्ड"-शैली के उदाहरण देखेंगे। बल्ले के अधिकार, मैं ध्यान दूंगा कि हमारे उदाहरण संकलन-समय की बुनाई का उपयोग करेंगे । सबसे पहले, हमें अपनी pom.xml फ़ाइल में निम्नलिखित डिपेंडेंसी को जोड़ना होगा :
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.9.5</version>
</dependency>
एक नियम के रूप में, विशेष ajc संकलक यह है कि हम पहलुओं का उपयोग कैसे करते हैं। IntelliJ IDEA में यह डिफ़ॉल्ट रूप से शामिल नहीं है, इसलिए इसे एप्लिकेशन कंपाइलर के रूप में चुनते समय, आपको 5168 75 AspectJ वितरण के लिए पथ निर्दिष्ट करना होगा। यह पहला तरीका था। दूसरा, जो मैंने उपयोग किया है, निम्नलिखित प्लगइन को pom.xml फ़ाइल में पंजीकृत करना है:
<build>
  <plugins>
     <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
           <complianceLevel>1.8</complianceLevel>
           <source>1.8</source>
           <target>1.8</target>
           <showWeaveInfo>true</showWeaveInfo>
           <<verbose>true<verbose>
           <Xlint>ignore</Xlint>
           <encoding>UTF-8</encoding>
        </configuration>
        <executions>
           <execution>
              <goals>
                 <goal>compile</goal>
                 <goal>test-compile</goal>
              </goals>
           </execution>
        </executions>
     </plugin>
  </plugins>
</build>
इसके बाद, मेवेन से पुनः आयात करना और एमवीएन क्लीन कंपाइल चलाना एक अच्छा विचार है । अब सीधे उदाहरणों पर चलते हैं।

उदाहरण संख्या 1

चलिए एक मुख्य वर्ग बनाते हैं। इसमें, हमारे पास एक प्रवेश बिंदु और एक विधि होगी जो कंसोल पर पास किए गए नाम को प्रिंट करती है:
public class Main {

  public static void main(String[] args) {
  printName("Tanner");
  printName("Victor");
  printName("Sasha");
  }

  public static void printName(String name) {
     System.out.println(name);
  }
}
यहाँ कुछ भी जटिल नहीं है। हमने एक नाम पारित किया और इसे कंसोल पर प्रदर्शित किया। यदि हम अभी प्रोग्राम चलाते हैं, तो हम कंसोल पर निम्नलिखित देखेंगे:
टान्नर विक्टर साशा
तो अब, एओपी की शक्ति का लाभ उठाने का समय आ गया है। अब हमें एक आस्पेक्ट फाइल बनाने की जरूरत है। वे दो प्रकार के होते हैं: पहले में .aj फ़ाइल एक्सटेंशन होता है। दूसरा सामान्य वर्ग है जो एओपी क्षमताओं को लागू करने के लिए एनोटेशन का उपयोग करता है। आइए सबसे पहले .aj एक्सटेंशन वाली फाइल को देखें:
public aspect GreetingAspect {

  pointcut greeting() : execution(* Main.printName(..));

  before() : greeting() {
     System.out.print("Hi, ");
  }
}
यह फाइल एक क्लास की तरह है। आइए देखें कि यहां क्या हो रहा है: पॉइंटकट जॉइन पॉइंट्स का एक सेट है; ग्रीटिंग () इस पॉइंटकट का नाम है; : निष्पादन Main.printName(...) विधि के सभी ( * ) कॉल के निष्पादन के दौरान इसे लागू करने का संकेत देता है । इसके बाद एक विशिष्ट सलाह आती है - पहले () - जिसे लक्ष्य विधि कहे जाने से पहले निष्पादित किया जाता है। : ग्रीटिंग () वह कटपॉइंट है जिसका यह सलाह जवाब देती है। ठीक है, और नीचे हम विधि के शरीर को ही देखते हैं, जो कि जावा भाषा में लिखा गया है, जिसे हम समझते हैं। जब हम इस पहलू के साथ मुख्य चलाते हैं , तो हमें यह कंसोल आउटपुट मिलेगा:
हाय, टान्नर हाय, विक्टर हाय, साशा
हम देख सकते हैं कि PrintName पद्धति के प्रत्येक कॉल को एक पहलू के कारण संशोधित किया गया है। अब देखते हैं कि एनोटेशन के साथ जावा क्लास के रूप में पहलू कैसा दिखेगा:
@Aspect
public class GreetingAspect{

  @Pointcut("execution(* Main.printName(String))")
  public void greeting() {
  }

  @Before("greeting()")
  public void beforeAdvice() {
     System.out.print("Hi, ");
  }
}
.aj पहलू फ़ाइल के बाद , यहाँ सब कुछ और अधिक स्पष्ट हो जाता है:
  • @Aspect इंगित करता है कि यह वर्ग एक पहलू है;
  • @Pointcut("execution(* Main.printName(String))") वह कटपॉइंट है जो Main.printName के सभी कॉल के लिए एक इनपुट तर्क के साथ ट्रिगर होता है जिसका प्रकार String है ;
  • @Before("greeting()") सलाह है जो ग्रीटिंग() कटपॉइंट में निर्दिष्ट कोड को कॉल करने से पहले लागू की जाती है ।
इस पहलू के साथ मुख्य चलाने से कंसोल आउटपुट नहीं बदलता है:
हाय, टान्नर हाय, विक्टर हाय, साशा

उदाहरण संख्या 2

मान लीजिए कि हमारे पास कुछ विधि है जो ग्राहकों के लिए कुछ संचालन करती है, और हम इस विधि को मुख्य से कहते हैं :
public class Main {

  public static void main(String[] args) {
  performSomeOperation("Tanner");
  }

  public static void performSomeOperation(String clientName) {
     System.out.println("Performing some operations for Client " + clientName);
  }
}
आइए "छद्म लेनदेन" बनाने के लिए @Around एनोटेशन का उपयोग करें:
@Aspect
public class TransactionAspect{

  @Pointcut("execution(* Main.performSomeOperation(String))")
  public void executeOperation() {
  }

  @Around(value = "executeOperation()")
  public void beforeAdvice(ProceedingJoinPoint joinPoint) {
     System.out.println("Opening a transaction...");
     try {
        joinPoint.proceed();
        System.out.println("Closing a transaction...");
     }
     catch (Throwable throwable) {
        System.out.println("The operation failed. Rolling back the transaction...");
     }
  }
  }
ProceedingJoinPoint ऑब्जेक्ट की आगे बढ़ने की विधि के साथ , हम सलाह में इसका स्थान निर्धारित करने के लिए रैपिंग विधि कहते हैं। इसलिए, उपरोक्त विधि में कोड joinPoint.proceed(); बिफोर है , जबकि इसके नीचे का कोड आफ्टर है । यदि हम main चलाते हैं , तो हमें यह कंसोल में मिलता है:
लेन-देन खोलना... क्लाइंट टैनर के लिए कुछ कार्रवाइयाँ करना लेन-देन बंद करना...
लेकिन अगर हम अपने तरीके में फेंक देते हैं और अपवाद करते हैं (असफल ऑपरेशन का अनुकरण करने के लिए):
public static void performSomeOperation(String clientName) throws Exception {
  System.out.println("Performing some operations for Client " + clientName);
  throw new Exception();
}
तब हमें यह कंसोल आउटपुट मिलता है:
लेन-देन खोल रहा है... क्लाइंट टैनर के लिए कुछ कार्रवाइयाँ कर रहा है कार्रवाई विफल रही। लेन-देन वापस लाया जा रहा है...
तो हमें यहाँ जो मिला वह एक प्रकार की त्रुटि से निपटने की क्षमता है।

उदाहरण संख्या 3

हमारे अगले उदाहरण में, कंसोल में लॉग इन करने जैसा कुछ करते हैं। सबसे पहले, मुख्य पर एक नज़र डालें , जहाँ हमने कुछ छद्म व्यावसायिक तर्क जोड़े हैं:
public class Main {
  private String value;

  public static void main(String[] args) throws Exception {
     Main main = new Main();
     main.setValue("<some value>");
     String valueForCheck = main.getValue();
     main.checkValue(valueForCheck);
  }

  public void setValue(String value) {
     this.value = value;
  }

  public String getValue() {
     return this.value;
  }

  public void checkValue(String value) throws Exception {
     if (value.length() > 10) {
        throw new Exception();
     }
  }
}
main में , हम वैल्यू इंस्टेंस वेरिएबल को वैल्यू असाइन करने के लिए setValue का उपयोग करते हैं। फिर हम मान प्राप्त करने के लिए getValue का उपयोग करते हैं, और फिर हम यह देखने के लिए checkValue कहते हैं कि यह 10 वर्णों से अधिक लंबा है या नहीं। यदि ऐसा है, तो एक अपवाद फेंका जाएगा। अब आइए उस पहलू को देखें जिसका उपयोग हम विधियों के कार्य को लॉग करने के लिए करेंगे:
@Aspect
public class LogAspect {

  @Pointcut("execution(* *(..))")
  public void methodExecuting() {
  }

  @AfterReturning(value = "methodExecuting()", returning = "returningValue")
  public void recordSuccessfulExecution(JoinPoint joinPoint, Object returningValue) {
     if (returningValue != null) {
        System.out.printf("Successful execution: method — %s method, class — %s class, return value — %s\n",
              joinPoint.getSignature().getName(),
              joinPoint.getSourceLocation().getWithinType().getName(),
              returningValue);
     }
     else {
        System.out.printf("Successful execution: method — %s, class — %s\n",
              joinPoint.getSignature().getName(),
              joinPoint.getSourceLocation().getWithinType().getName());
     }
  }

  @AfterThrowing(value = "methodExecuting()", throwing = "exception")
  public void recordFailedExecution(JoinPoint joinPoint, Exception exception) {
     System.out.printf("Exception thrown: method — %s, class — %s, exception — %s\n",
           joinPoint.getSignature().getName(),
           joinPoint.getSourceLocation().getWithinType().getName(),
           exception);
  }
}
यहाँ क्या चल रहा है? @Pointcut("निष्पादन (* *(..))") सभी विधियों की सभी कॉलों में शामिल हो जाएगा। @AfterReturning(value = "methodExecuting()", returning = "returningValue") वह सलाह है जिसे लक्ष्य विधि के सफल निष्पादन के बाद क्रियान्वित किया जाएगा। हमारे यहां दो मामले हैं:
  1. जब विधि का रिटर्न मान होता है — if (returningValue! = Null) {
  2. जब कोई रिटर्न वैल्यू नहीं है - और {
@AfterThrowing(value = "methodExecuting()",फेंकना = "अपवाद") एक सलाह है जो एक त्रुटि के मामले में ट्रिगर की जाएगी, अर्थात, जब विधि एक अपवाद फेंकती है। और तदनुसार, मुख्य चलाकर , हमें एक प्रकार का कंसोल-आधारित लॉगिंग मिलेगा:
सफल निष्पादन: विधि - सेटवैल्यू, वर्ग - मुख्य सफल निष्पादन: विधि - getValue, वर्ग - मुख्य, वापसी मूल्य - <कुछ मूल्य> अपवाद फेंका गया: विधि - चेकवैल्यू, वर्ग - मुख्य अपवाद - java.lang.Exception अपवाद फेंका गया: विधि - मुख्य, वर्ग - मुख्य, अपवाद - java.lang.Exception
और चूंकि हमने अपवादों को हैंडल नहीं किया, हमें अभी भी एक स्टैक ट्रेस मिलेगा: एओपी क्या है?  आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग के सिद्धांत - 3आप इन लेखों में अपवादों और अपवाद प्रबंधन के बारे में पढ़ सकते हैं: अपवाद जावा में और अपवाद: पकड़ना और संभालना । आज मेरे लिए बस इतना ही। आज हम AOP से परिचित हुए , और आप यह देखने में सक्षम हुए कि यह जानवर उतना डरावना नहीं है जितना कुछ लोग इसे समझते हैं। सभी को अलविदा!
टिप्पणियां
  • लोकप्रिय
  • नया
  • पुराना
टिप्पणी लिखने के लिए आपको साइन इन करना होगा
इस पेज पर अभी तक कोई टिप्पणियां नहीं हैं