有时在查看代码时,我看到许多方法都指定了注释:

@SuppressWarnings("unchecked")

这是什么意思?


当前回答

SuppressWarning注释用于对带注释的元素禁用编译器警告。具体来说,未检查的类别允许抑制因未检查的类型强制转换而生成的编译器警告。

其他回答

@SuppressWarnings注释是JDK中可用的三个内置注释之一,在Java 1.5中与@Override和@Deprecated一起添加。

@SuppressWarnings指示编译器忽略或抑制注释元素中指定的编译器警告以及该元素中的所有程序元素。 例如,如果对一个类进行了注释以抑制特定的警告,那么在该类内部的方法中生成的警告也将被分离。

您可能已经看到了@SuppressWarnings(“unchecked”)和@SuppressWarnings(“serial”),这是@SuppressWarnings注释的两个最流行的示例。前者用于抑制由于未经检查的强制转换而产生的警告,而后者用于提醒在Serializable类中添加SerialVersionUID。

阅读更多信息:https://javarevisited.blogspot.com/2015/09/what-is-suppresswarnings-annotation-in-java-unchecked-raw-serial.html#ixzz5rqQaOLUa

简单地说:这是一个警告,编译器通过它表示它不能确保类型安全。

例如,JPA服务方法:

@SuppressWarnings("unchecked")
public List<User> findAllUsers(){
    Query query = entitymanager.createQuery("SELECT u FROM User u");
    return (List<User>)query.getResultList();
}

如果我没有注释@SuppressWarnings(“unchecked”)在这里,它将有一个问题与行,我想返回我的ResultList。

简单地说,类型安全的意思是:如果一个程序在编译时没有错误和警告,并且在运行时没有引发任何意外的ClassCastException,则该程序被认为是类型安全的。

我建立在http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html上

SuppressWarning注释用于对带注释的元素禁用编译器警告。具体来说,未检查的类别允许抑制因未检查的类型强制转换而生成的编译器警告。

在Java中,泛型是通过类型擦除实现的。例如,下面的代码。

List<String> hello = List.of("a", "b");
String example = hello.get(0);

编译为以下内容。

List hello = List.of("a", "b");
String example = (String) hello.get(0);

和列表。的定义为。

static <E> List<E> of(E e1, E e2);

在类型擦除后变成。

static List of(Object e1, Object e2);

编译器在运行时不知道什么是泛型类型,所以如果你写这样的东西。

Object list = List.of("a", "b");
List<Integer> actualList = (List<Integer>) list;

Java虚拟机在运行程序时不知道泛型类型是什么,所以这个编译并运行,对于Java虚拟机,这是一个转换为List类型(这是它唯一可以验证的东西,所以它只验证它)。

现在加上这条线。

Integer hello = actualList.get(0);

当Java编译器插入隐式强制转换时,JVM将抛出一个意外的ClassCastException。

java.lang.ClassCastException: java.base/java.lang.String cannot be cast to java.base/java.lang.Integer

未检查的警告告诉程序员,强制转换可能导致程序在其他地方抛出异常。使用@SuppressWarnings("unchecked")取消警告告诉编译器,程序员相信代码是安全的,不会导致意外异常。

你为什么要这么做?Java类型系统不足以表示所有可能的类型使用模式。有时您可能知道强制转换是安全的,但Java并没有提供这样的方法—为了隐藏这样的警告,可以使用@SupressWarnings(“unchecked”),这样程序员就可以专注于真正的警告。例如,Optional.empty()返回一个单例,以避免分配不存储值的空可选项。

private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}

这种类型转换是安全的,因为存储在空可选对象中的值无法检索,因此不存在意外类类型转换异常的风险。

据我所知,目前它与抑制关于泛型的警告有关;泛型是一种新的编程结构,在JDK 5之前的版本中不支持,因此任何新旧结构的混合都可能导致一些意想不到的结果。

编译器会警告程序员,但是如果程序员已经知道了,他们可以使用SuppressWarnings关闭这些可怕的警告。