Error: pattern matching with switch on InetAddress fail with ‘does not cover all possible input values’

In Java, pattern matching with switch statements or expressions can fail with a compiler error like:

'does not cover all possible input values'

This happens because the compiler requires exhaustive coverage of all possible cases for a given type. For InetAddress, which is a non-sealed abstract class, the compiler cannot ensure that all possible subclasses of InetAddress are covered.


Key Concepts

  1. Exhaustiveness Check:
    • For switch to work, all possible types must be covered explicitly, or a default case must be provided.
    • This is achievable for enum types, sealed classes, or when you use a default branch.
  2. InetAddress Hierarchy:
    • InetAddress is an abstract class with two known direct subclasses in the standard library: Inet4Address and Inet6Address.
    • However, InetAddress is not sealed, meaning additional, user-defined subclasses can exist. The compiler cannot assume that Inet4Address and Inet6Address are the only subclasses.

Example of the Problem

import java.net.InetAddress;

public class InetAddressSwitch {
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getByName("127.0.0.1");

switch (address) {
case Inet4Address inet4Address -> System.out.println("IPv4 Address");
case Inet6Address inet6Address -> System.out.println("IPv6 Address");
}
}
}

Compiler Error:

The switch statement does not cover all possible input values.

Why Does This Happen?

The compiler cannot verify that all possible subclasses of InetAddress are handled because:

  • InetAddress is not sealed (in Java 17 or later).
  • New, user-defined subclasses of InetAddress could exist, making the hierarchy open-ended.

Fixes

1. Add a default Case

The simplest fix is to provide a default case to handle any unmatched values.

import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;

public class InetAddressSwitch {
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getByName("127.0.0.1");

switch (address) {
case Inet4Address inet4Address -> System.out.println("IPv4 Address");
case Inet6Address inet6Address -> System.out.println("IPv6 Address");
default -> System.out.println("Unknown Address Type");
}
}
}

2. Use instanceof for Pattern Matching

If you’re using an earlier Java version or want to avoid switch, you can use instanceof.

import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;

public class InetAddressInstanceOf {
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getByName("127.0.0.1");

if (address instanceof Inet4Address) {
System.out.println("IPv4 Address");
} else if (address instanceof Inet6Address) {
System.out.println("IPv6 Address");
} else {
System.out.println("Unknown Address Type");
}
}
}

3. Manually Verify Exhaustiveness

If you are confident that no other subclasses of InetAddress will appear (e.g., in a controlled environment), you can suppress the compiler warning (not recommended in most cases).


Key Takeaways

  1. The error occurs because the switch cannot guarantee that all possible subclasses of InetAddress are handled.
  2. To resolve the issue:
    • Add a default case to handle unmatched cases.
    • Use instanceof checks as an alternative to switch.
  3. This limitation arises from InetAddress being non-sealed, allowing user-defined subclasses that the compiler cannot anticipate.

No images available.