Hello! Using generic varargs in non-final (in particular, interface) methods is still painful in Java, as one cannot annotate them as @SafeVarargs, so every callsite has an unwanted warning about generic array creation.
Closed sealed hierarchies allow to control all the implementations and explicitly mark all of them with @SafeVarargs. In this case, we could improve the situation if we allow marking the parent method as well. E.g., consider the following code: import java.util.Optional; public class Main { public sealed interface Service permits ServiceImpl { @SuppressWarnings("unchecked") // cannot use @SafeVarargs here <W> void process(Optional<W>... params); } public static final class ServiceImpl implements Service { @SafeVarargs @Override public final <W> void process(Optional<W>... params) { for (Optional<W> param : params) { param.ifPresent(System.out::println); } } } void test(Service service, ServiceImpl serviceImpl) { // Warning: warning: [unchecked] unchecked generic array creation service.process(Optional.of(1), Optional.of(2), Optional.empty()); // No warning thanks to SafeVarargs serviceImpl.process(Optional.of(1), Optional.of(2), Optional.empty()); } } Here, we cannot use the Service::process method without an unchecked warning about generic array creation. Which is bad, as we have closed hierarchy and explicitly marked all the implementations as safe. To improve the situation, I suggest the following additions to the Java language specification: 1. Allow marking non-final, non-private methods (abstract or not) with @SafeVarargs if they are declared inside a sealed or final (*) class / interface 2. If a vararg method overrides / implements another vararg method marked with SafeVarargs, then the overriding method must be marked with SafeVarargs as well; otherwise a compilation error occurs. 3. If a non-sealed class / interface is declared, all its visible methods are examined. If any of them is overridable and marked with SafeVarargs, then a compilation error occurs. (*) Extending this to final classes is not quite necessary, but it looks logical addition and allows to omit final method modifier inside final class. With these rules, the code above could be rewritten as: import java.util.Optional; public class Main { public sealed interface Service permits ServiceImpl { @SafeVarargs // now allowed, as we are inside sealed interface <W> void process(Optional<W>... params); } public static final class ServiceImpl implements Service { @SafeVarargs // must be specified @Override public <W> void process(Optional<W>... params) { // possible to omit 'final' here for (Optional<W> param : params) { param.ifPresent(System.out::println); } } } void test(Service service, ServiceImpl serviceImpl) { // No warning anymore thanks to SafeVarargs service.process(Optional.of(1), Optional.of(2), Optional.empty()); // No warning thanks to SafeVarargs serviceImpl.process(Optional.of(1), Optional.of(2), Optional.empty()); } } What do you think? With best regards, Tagir Valeev