ZetCode

Java Deprecated Annotation

Last modified: April 13, 2025

The @Deprecated annotation in Java marks program elements that should no longer be used. It indicates that the element is obsolete and may be removed in future versions. Using deprecated elements may lead to compatibility issues or unexpected behavior.

When a class, method, or field is marked as deprecated, developers should avoid using it in new code. The Java compiler generates warnings when deprecated elements are used. The annotation helps maintain backward compatibility while encouraging migration to newer alternatives.

Deprecated Annotation Basics

The @Deprecated annotation is part of the java.lang package. It can be applied to classes, methods, fields, constructors, and other program elements. There are two forms of the annotation: the simple marker and the version with attributes.

@Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER,TYPE})
@Retention(value=RUNTIME)
public @interface Deprecated {
    String since() default "";
    boolean forRemoval() default false;
}

The annotation definition shows it can specify when the element was deprecated (since) and whether it's scheduled for removal (forRemoval). These attributes provide additional context about the deprecation.

Simple Deprecation Example

This example demonstrates basic usage of the @Deprecated annotation on a method. The compiler will generate warnings when this method is used.

Main.java
package com.zetcode;

class Calculator {
    /**
     * @deprecated This method is deprecated because it uses integer division.
     * Use {@link #divide(double, double)} instead.
     */
    @Deprecated
    public int divide(int a, int b) {
        return a / b;
    }
    
    public double divide(double a, double b) {
        return a / b;
    }
}

public class Main {

    public static void main(String[] args) {
        Calculator calc = new Calculator();
        // Generates compiler warning
        int result = calc.divide(10, 3);
        System.out.println("Deprecated method result: " + result);
        
        // Preferred alternative
        double preciseResult = calc.divide(10.0, 3.0);
        System.out.println("New method result: " + preciseResult);
    }
}

The example shows a deprecated integer division method with a Javadoc @deprecated tag explaining why it's deprecated and suggesting an alternative. The new method provides more precise floating-point division.

Deprecation with since and forRemoval

This example shows how to use the since and forRemoval attributes to provide more information about the deprecation status.

Main.java
package com.zetcode;

class OldAPI {
    /**
     * @deprecated This field was deprecated in version 2.5 and will be removed
     * in a future release. Use {@link #NEW_CONSTANT} instead.
     */
    @Deprecated(since = "2.5", forRemoval = true)
    public static final String OLD_CONSTANT = "old";
    
    public static final String NEW_CONSTANT = "new";
}

public class Main {

    public static void main(String[] args) {
        // Generates stronger warning due to forRemoval=true
        System.out.println("Old constant: " + OldAPI.OLD_CONSTANT);
        
        // Preferred alternative
        System.out.println("New constant: " + OldAPI.NEW_CONSTANT);
    }
}

The since attribute indicates when the field was deprecated, while forRemoval=true signals it will be removed in a future version. This generates stronger compiler warnings to encourage immediate migration.

Deprecating an Entire Class

This example demonstrates how to deprecate an entire class and provide information about its replacement.

Main.java
package com.zetcode;

/**
 * @deprecated This class is deprecated as of version 3.0 because it uses
 * legacy encryption. Use {@link AESEncryptor} instead for better security.
 */
@Deprecated(since = "3.0")
class DESEncryptor {
    public String encrypt(String data) {
        // Legacy DES encryption logic
        return "DES:" + data;
    }
}

class AESEncryptor {
    public String encrypt(String data) {
        // Modern AES encryption logic
        return "AES:" + data;
    }
}

public class Main {

    public static void main(String[] args) {
        // Generates warning
        DESEncryptor oldEncryptor = new DESEncryptor();
        System.out.println(oldEncryptor.encrypt("secret"));
        
        // Preferred alternative
        AESEncryptor newEncryptor = new AESEncryptor();
        System.out.println(newEncryptor.encrypt("secret"));
    }
}

The example shows a deprecated encryption class with a suggested replacement. The Javadoc explains why the class is deprecated and what to use instead. Both the class annotation and Javadoc tag work together to communicate deprecation.

Deprecating a Constructor

This example demonstrates how to deprecate a constructor while providing alternative ways to create objects.

Main.java
package com.zetcode;

class Connection {
    private String url;
    private int timeout;
    
    /**
     * @deprecated This constructor is deprecated as of version 1.2 because
     * timeout should always be specified. Use {@link #Connection(String, int)}
     * or {@link #createDefault(String)} instead.
     */
    @Deprecated(since = "1.2")
    public Connection(String url) {
        this(url, 5000); // Default timeout
    }
    
    public Connection(String url, int timeout) {
        this.url = url;
        this.timeout = timeout;
    }
    
    public static Connection createDefault(String url) {
        return new Connection(url, 5000);
    }
}

public class Main {

    public static void main(String[] args) {
        // Generates warning
        Connection conn1 = new Connection("http://example.com");
        
        // Preferred alternatives
        Connection conn2 = new Connection("http://example.com", 3000);
        Connection conn3 = Connection.createDefault("http://example.com");
    }
}

The example deprecates a constructor that uses a default timeout value. Two alternatives are provided: a constructor with explicit timeout and a factory method. This shows how to guide users toward better practices while maintaining backward compatibility.

Suppressing Deprecation Warnings

This example shows how to suppress deprecation warnings when you must use deprecated code, such as during migration or testing.

Main.java
package com.zetcode;

class LegacySystem {
    /**
     * @deprecated This method will be removed in version 5.0. Use newAPI()
     * instead.
     */
    @Deprecated(since = "4.0", forRemoval = true)
    public void oldAPI() {
        System.out.println("Running old API");
    }
    
    public void newAPI() {
        System.out.println("Running new API");
    }
}

public class Main {
    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        LegacySystem system = new LegacySystem();
        
        // No warning due to @SuppressWarnings
        system.oldAPI();
        
        // Preferred alternative
        system.newAPI();
        
        testLegacyFeatures();
    }
    
    // Method to test deprecated features
    @SuppressWarnings("deprecation")
    private static void testLegacyFeatures() {
        LegacySystem testSystem = new LegacySystem();
        testSystem.oldAPI(); // No warning in test code
    }
}

The example uses @SuppressWarnings("deprecation") to silence warnings when using deprecated methods. This should be used sparingly and only when necessary, with clear justification in comments.

Deprecation in Interfaces

This example demonstrates how to deprecate interface methods and provide default implementations to help with migration.

Main.java
package com.zetcode;

interface PaymentProcessor {
    /**
     * @deprecated As of version 2.0, use processPayment(amount, currency)
     * instead. This method assumes USD which is not suitable for international
     * payments.
     */
    @Deprecated(since = "2.0")
    default void processPayment(double amount) {
        processPayment(amount, "USD");
    }
    
    void processPayment(double amount, String currency);
}

class OnlinePayment implements PaymentProcessor {
    @Override
    public void processPayment(double amount, String currency) {
        System.out.printf("Processing %.2f %s payment%n", amount, currency);
    }
}

public class Main {

    public static void main(String[] args) {
        PaymentProcessor processor = new OnlinePayment();
        
        // Generates warning
        processor.processPayment(100.0);
        
        // Preferred alternative
        processor.processPayment(100.0, "EUR");
    }
}

The example shows a deprecated default method in an interface with a better alternative. Default methods allow maintaining backward compatibility while encouraging migration to newer versions of the API.

Deprecation with Enum Constants

This example demonstrates how to deprecate specific enum constants while keeping others active.

Main.java
package com.zetcode;

enum Browser {
    /**
     * @deprecated Internet Explorer is no longer supported as of version 11.
     */
    @Deprecated(since = "2022")
    IE,
    CHROME,
    FIREFOX,
    EDGE
}

public class Main {

    public static void main(String[] args) {
        // Generates warning
        Browser deprecated = Browser.IE;
        System.out.println("Deprecated browser: " + deprecated);
        
        // Active browsers
        for (Browser browser : Browser.values()) {
            if (!browser.name().equals("IE")) {
                System.out.println("Supported browser: " + browser);
            }
        }
    }
}

The example deprecates the IE enum constant while keeping others active. This pattern is useful when phasing out support for specific options in an enum while maintaining the rest of the enumeration.

Source

Java Deprecated Annotation Documentation

In this tutorial, we've covered all aspects of the Java @Deprecated annotation with practical examples. Proper use of deprecation helps maintain backward compatibility while guiding users toward better alternatives.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.