Java uses Keyword

The uses keyword in Java is part of the Java Platform Module System (JPMS) introduced in Java 9. It is used within a module declaration to specify that the module depends on a service interface. This keyword indicates that the module will use a service provider that implements the specified service interface.

Table of Contents

  1. Introduction
  2. uses Keyword Syntax
  3. Understanding uses
  4. Examples
    • Declaring a Module that Uses a Service
    • Providing a Service
    • Using the Service
  5. Real-World Use Case
  6. Conclusion

Introduction

In Java’s module system, services and service providers can be declared and consumed using the uses and provides keywords. The uses keyword declares a dependency on a service, allowing the module to discover and use implementations of the service interface at runtime.

uses Keyword Syntax

The syntax for using the uses keyword in a module-info.java file is as follows:

module moduleName {
    uses fully.qualified.ServiceInterfaceName;
}

Example:

module com.example.myapp {
    uses com.example.myapp.api.MyService;
}

Understanding uses

Key Points:

  • Service Interface: The uses keyword specifies that the module depends on a service interface.
  • Service Loader: At runtime, the ServiceLoader class can be used to locate and load implementations of the service.
  • Decoupling: This mechanism helps decouple the service provider and the consumer, promoting modular design.

Examples

Declaring a Module that Uses a Service

A module that uses a service interface.

Example

// File: src/com.example.myapp/module-info.java
module com.example.myapp {
    uses com.example.myapp.api.MyService;
}

Providing a Service

A module that provides an implementation for the service interface.

Example

// File: src/com.example.provider/module-info.java
module com.example.provider {
    requires com.example.myapp;
    provides com.example.myapp.api.MyService with com.example.provider.MyServiceImpl;
}

// File: src/com.example.myapp/api/MyService.java
package com.example.myapp.api;

public interface MyService {
    void performService();
}

// File: src/com.example.provider/MyServiceImpl.java
package com.example.provider;

import com.example.myapp.api.MyService;

public class MyServiceImpl implements MyService {
    @Override
    public void performService() {
        System.out.println("Service performed by MyServiceImpl");
    }
}

Using the Service

Using the ServiceLoader to load and use the service implementation.

Example

// File: src/com.example.myapp/Main.java
package com.example.myapp;

import com.example.myapp.api.MyService;

import java.util.ServiceLoader;

public class Main {
    public static void main(String[] args) {
        ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);
        for (MyService service : serviceLoader) {
            service.performService();
        }
    }
}

Output:

Service performed by MyServiceImpl

Real-World Use Case

Plugin System

In real-world applications, the uses and provides keywords can be used to create a plugin system where the main application can discover and use plugins (service providers) at runtime without knowing the implementation details.

Example

// Main application module definition (src/com.example.app/module-info.java)
module com.example.app {
    uses com.example.plugin.api.Plugin;
}

// Plugin API module definition (src/com.example.plugin/module-info.java)
module com.example.plugin {
    exports com.example.plugin.api;
}

// Plugin provider module definition (src/com.example.plugin.impl/module-info.java)
module com.example.plugin.impl {
    requires com.example.plugin;
    provides com.example.plugin.api.Plugin with com.example.plugin.impl.PluginImpl;
}

// Plugin interface (src/com.example.plugin/api/Plugin.java)
package com.example.plugin.api;

public interface Plugin {
    void execute();
}

// Plugin implementation (src/com.example.plugin.impl/PluginImpl.java)
package com.example.plugin.impl;

import com.example.plugin.api.Plugin;

public class PluginImpl implements Plugin {
    @Override
    public void execute() {
        System.out.println("Plugin executed by PluginImpl");
    }
}

// Main application (src/com.example.app/Main.java)
package com.example.app;

import com.example.plugin.api.Plugin;

import java.util.ServiceLoader;

public class Main {
    public static void main(String[] args) {
        ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class);
        for (Plugin plugin : serviceLoader) {
            plugin.execute();
        }
    }
}

Output:

Plugin executed by PluginImpl

Conclusion

The uses keyword in Java’s module system is used for specifying service dependencies in a decoupled and modular way. By declaring a dependency on a service interface, modules can dynamically discover and use service implementations at runtime, promoting a flexible and extensible architecture. Understanding and using the uses keyword effectively is essential for developing modular and maintainable Java applications.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top