Подтвердить что ты не робот

Почему varargs (Class <? Extends Throwable>... t) "неконтролируемая или небезопасная" операция?

Хорошо, поэтому я вызываю метод с подписью (Class<? extends Throwable>... exceptions), и я получаю сообщение "File.java использует непроверенные или небезопасные операции" здесь в основном методе:

public class VarargsFun {
    public void onException(Class<? extends Throwable>... exceptions) { }

    public static void main(String[] args) {
        new VarargsFun().onException(IllegalArgumentException.class);
    }
}

Не следует ли компилятору видеть, что IllegalArgumentException действительно расширяет RuntimeException, Exception и Throwable?

Как правильно изменить свой код, чтобы избавиться от этого предупреждения?

Мне действительно не хочется создавать свои исключения... кажется, лучше использовать .class

(не хотите использовать @SuppressWarnings!)

Am использует java 7. Спасибо за любые советы.

4b9b3361

Ответ 1

Поскольку varargs на самом деле являются просто массивами, а generics и массивы не смешиваются (ну), Java традиционно выдавал предупреждение, когда вы вызываете метод с общим тип vararg. Это связано с тем, что массив создается у вызывающего.

Однако вскоре стало очевидно, что массивы, созданные исключительно для передачи в метод varargs, не страдают от той же опасности, что и обычные общие массивы с точки зрения вызывающего, однако сам метод, получивший общий массив, может злоупотреблять ими. Поэтому в Java 7 forward предупреждение появляется в самом методе (в вашем случае onException) и может быть подавлено с помощью @SafeVarargs аннотация по методу:

@SafeVarargs
public void onException(Class<? extends Throwable>... exceptions) { }

Если вы на самом деле не используете язык Java 7 или не можете изменить onException (предположительно, потому что это метод библиотеки), вы можете безопасно использовать @SuppressWarnings, чтобы скрыть это предупреждение:

@SuppressWarnings("unchecked")
public static void main(String[] args) {
    new VarargsFun().onException(IllegalArgumentException.class);
}

Если вы подавляете предупреждения таким образом, будьте осторожны, чтобы изолировать это выражение в своем собственном методе, чтобы вы случайно не подавили другие будущие предупреждения.

Лично я полностью отключу общие предупреждения vararg в моей среде IDE, потому что они почти никогда не указывают неправильный код с точки зрения вызывающего.

Ответ 2

Проще всего понять, понимаете ли вы, что

new VarargsFun().onException(IllegalArgumentException.class);

- это просто синтаксический сахар для

new VarargsFun().onException(
    new Class<? extends Throwable>[]{ IllegalArgumentException.class });

то есть. сайт вызова создает массив с типом компонента, равным типу varargs.

Но, конечно, new Class<? extends Throwable>[] не допускается в Java. Поэтому компилятор делает new Class<?>[] вместо этого и выдает предупреждение.