Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Java

Java 9 मॉड्यूल सिस्टम: module-info.java में requires क्लॉज

Java 9 मॉड्यूल सिस्टम में, module-info.java में requires क्लॉज मॉड्यूल निर्भरताओं की घोषणा करता है। डिफ़ॉल्ट रूप से, एक मॉड्यूल मॉड्यूल पथ पर अन्य मॉड्यूल्स को नहीं देख सकता - प्रत्येक निर्भरता को स्पष्ट रूप से घोषित किया जाना चाहिए।

requires क्लॉज के प्रकार

1. साधारण आवश्यकता: requires <module>

मॉड्यूल पर अनिवार्य निर्भरता घोषित करता है। संकलन और रनटाइम दोनों पर आवश्यक।

module com.tutorialspoint.gui {
    requires com.tutorialspoint.model;
    requires java.desktop;
    requires java.sql;
    requires org.slf4j;
}

2. पारगमन आवश्यकता: requires transitive <module>

निर्भरता को उन मॉड्यूल्स के लिए अंतर्निहित बनाता है जो इस मॉड्यूल पर निर्भर करते हैं। "API रिसाव" को कम करता है।

// com.tutorialspoint.model आंतरिक रूप से com.core का उपयोग करता है
// और इसके API में com.core प्रकार लौटाता है
module com.tutorialspoint.model {
    requires transitive com.core;  // उपभोक्ताओं को com.core की आवश्यकता नहीं
}

// उपभोक्ता को केवल आवश्यकता है:
module com.tutorialspoint.gui {
    requires com.tutorialspoint.model;  // com.core स्वचालित रूप से उपलब्ध
    // requires com.core;  // आवश्यक नहीं!
}

3. स्थैतिक आवश्यकता: requires static <module>

वैकल्पिक रनटाइम निर्भरता - संकलन के लिए अनिवार्य, रनटाइम के लिए वैकल्पिक।

module com.tutorialspoint.model {
    // संकलन के लिए आवश्यक (कंपाइल-समय निर्भरता)
    // रनटाइम पर वैकल्पिक - अनुपस्थित होने पर भी एप्लिकेशन शुरू होता है
    requires static oracle.jdbc;        // Oracle JDBC ड्राइवर
    requires static com.h2database.h2;  // H2 डेटाबेस
}
पहलूसाधारणtransitivestatic
संकलनआवश्यकआवश्यकआवश्यक
रनटाइमआवश्यकआवश्यकवैकल्पिक
उपभोक्ताओं के लिए दृश्यमाननहींहां (अंतर्निहित)नहीं
उपयोग केसमानक निर्भरताAPI में प्रकार रिसाववैकल्पिक रनटाइम डिपेंडेंसी

पूर्ण module-info.java उदाहरण

module com.example.ecommerce {
    // मानक निर्भरताएं
    requires java.sql;
    requires java.logging;
    requires com.fasterxml.jackson.databind;
    
    // पारगमन: हमारा API jakarta.persistence प्रकारों को उजागर करता है
    requires transitive jakarta.persistence;
    
    // वैकल्पिक रनटाइम निर्भरताएं
    requires static org.postgresql;      // PostgreSQL ड्राइवर
    requires static com.h2database.h2;   // H2 डेटाबेस (टेस्टिंग)
    requires static org.mongodb.driver;  // MongoDB (वैकल्पिक फीचर)
    
    // निर्यात
    exports com.example.ecommerce.api;
    exports com.example.ecommerce.model;
    
    // सेवाएं
    uses com.example.ecommerce.spi.PaymentGateway;
    provides com.example.ecommerce.spi.PaymentGateway
        with com.example.ecommerce.impl.StripeGateway;
}

रिफ्लेक्शन और रनटाइम जांच

import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Requires;
import java.util.Set;

public class RequiresInspector {
    public static void main(String[] args) {
        ModuleDescriptor descriptor = ModuleDescriptor.readModuleDescriptor(
            java.nio.file.Path.of("mods/com.example.ecommerce/module-info.class"));
        
        System.out.println("मॉड्यूल: " + descriptor.name());
        System.out.println("\nआवश्यकताएं:");
        
        for (Requires requires : descriptor.requires()) {
            StringBuilder sb = new StringBuilder("  requires");
            if (requires.isTransitive()) sb.append(" transitive");
            if (requires.isStatic()) sb.append(" static");
            sb.append(" ").append(requires.name());
            if (requires.modifiers().contains(Requires.Modifier.MANDATED)) {
                sb.append(" (mandated)");
            }
            System.out.println(sb);
        }
        
        System.out.println("\nनिर्यात: " + descriptor.exports());
        System.out.println("उपयोग: " + descriptor.uses());
        System.out.println("प्रदान: " + descriptor.provides());
    }
}

संकलन और रनटाइम व्यवहार

संकलन समय

  • सभी requires (साधारण, transitive, static) मॉड्यूल पथ पर मौजूद होने चाहिए
  • अनुपस्थित requires static → संकलन त्रुटि
  • requires transitive उपभोक्ता मॉड्यूल्स के लिए निर्भरता अंतर्निहित करता है

रनटाइम

  • साधारण और transitive: मॉड्यूल पथ पर मौजूद होना चाहिए
  • static: अनुपस्थित होने पर भी एप्लिकेशन शुरू होता है
  • रनटाइम पर अनुपस्थित static मॉड्यूल का उपयोग करने का प्रयास → NoClassDefFoundError या ModuleNotFoundException

सर्वोत्तम अभ्यास

  • डिफ़ॉल्ट रूप से साधारण requires का उपयोग करें - स्पष्ट निर्भरताएं बेहतर हैं
  • transitive का उपयोग करें जब: आपका सार्वजनिक API किसी अन्य मॉड्यूल के प्रकारों को लौटाता/स्वीकार करता है
  • static का उपयोग करें जब: वैकल्पिक रनटाइम निर्भरता (एकाधिक डेटाबेस ड्राइवर, वैकल्पिक फीचर)
  • चक्रीय निर्भरताओं से बचें: मॉड्यूल ग्राफ चक्रीय नहीं होना चाहिए
  • न्यूनतम निर्यात करें: केवल वही निर्यात करें जो वास्तव में API का हिस्सा है

सामान्य पैटर्न

API मॉड्यूल (कोई कार्यान्वयन निर्भरता नहीं)

module com.example.api {
    exports com.example.api;
    // कोई requires नहीं - शुद्ध API
}

कार्यान्वयन मॉड्यूल

module com.example.impl {
    requires transitive com.example.api;  // API निर्यात करता है
    requires java.sql;
    requires static org.postgresql;
    
    // कोई निर्यात नहीं - केवल सेवा प्रदाता
    provides com.example.api.Service with com.example.impl.ServiceImpl;
}

एप्लिकेशन मॉड्यूल

module com.example.app {
    requires com.example.api;
    requires com.example.impl;  // रनटाइम पर कार्यान्वयन चुनें
    requires java.logging;
}
  1. - जावा में ऑब्जेक्ट क्लोनिंग का उपयोग क्या है?

    ऑब्जेक्ट क्लोनिंग एक ऑब्जेक्ट की सटीक कॉपी बनाने का तरीका है। इस उद्देश्य के लिए, ऑब्जेक्ट क्लास के clone() मेथड का उपयोग ऑब्जेक्ट को क्लोन करने के लिए किया जाता है। जिस क्लास के ऑब्जेक्ट को क्लोन करना है, उसे Cloneable इंटरफेस को लागू करना होगा। यदि हम Cloneable इंटरफेस को लागू नहीं करते हैं, तो c

  1. - Java में StrictMath क्लास का उपयोग क्या है?

    java.lang.StrictMath एक फाइनल क्लास है और यह Object क्लास का एक सबक्लास है। StrictMath क्लास में बेसिक न्यूमेरिक ऑपरेशन करने के लिए मेथड्स होते हैं जैसे कि प्राथमिक एक्सपोनेंशियल, लॉगरिदम, स्क्वायर रूट, और ट्रिग्नोमेट्रिक फंक्शन्स। हमें StrictMath क्लास के लिए इंस्टेंस बनाने की आवश्यकता नहीं है क्यो

  1. Java में setBounds() विधि का उपयोग क्या है? Java में setBounds() विधि का उपयोग क्या है?

    लेआउट प्रबंधक जोड़े गए घटकों की स्थिति और आकार को स्वचालित रूप से तय करने के लिए उपयोग किए जाते हैं। लेआउट प्रबंधक की अनुपस्थिति में, घटकों की स्थिति और आकार को मैन्युअल रूप से सेट करना पड़ता है। ऐसी स्थिति में setBounds() विधि का उपयोग स्थिति और आकार सेट करने के लिए किया जाता है। घटकों की स्थिति औ