5.1.9. Unchecked Conversion

Let G name a generic type declaration with n type parameters.

There is an unchecked conversion from the raw class or interface type (§4.8) G to any parameterized type of the form G<T1,...,Tn>.

There is an unchecked conversion from the raw array type G[] to any array type type of the form G<T1,...,Tn>[].

Use of an unchecked conversion causes a compile-time unchecked warning unless G<...> is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1), or the unchecked warning is suppressed by the SuppressWarnings annotation (§9.6.3.5).

Unchecked conversion is used to enable a smooth interoperation of legacy code, written before the introduction of generic types, with libraries that have undergone a conversion to use genericity (a process we call generification). In such circumstances (most notably, clients of the Collections Framework in java.util), legacy code uses raw types (e.g. Collection instead of Collection<String>). Expressions of raw types are passed as arguments to library methods that use parameterized versions of those same types as the types of their corresponding formal parameters.

Such calls cannot be shown to be statically safe under the type system using generics. Rejecting such calls would invalidate large bodies of existing code, and prevent them from using newer versions of the libraries. This in turn, would discourage library vendors from taking advantage of genericity. To prevent such an unwelcome turn of events, a raw type may be converted to an arbitrary invocation of the generic type declaration to which the raw type refers. While the conversion is unsound, it is tolerated as a concession to practicality. An unchecked warning is issued in such cases.

5.5.2. Checked Casts and Unchecked Casts

A cast from a type S to a type T is statically known to be correct if and only if S <: T (§4.10).

A cast from a type S to a parameterized type (§4.5) T is unchecked unless at least one of the following conditions holds:

  • S <: T

  • All of the type arguments (§4.5.1) of T are unbounded wildcards

  • T <: S and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T.

A cast from a type S to a type variable T is unchecked unless S <: T.

An unchecked cast from S to T is completely unchecked if the cast from |S| to |T| is statically known to be correct. Otherwise, it is partially unchecked.

An unchecked cast causes a compile-time unchecked warning, unless suppressed by the SuppressWarnings annotation (§9.6.3.5).

A cast is checked if it is not statically known to be correct and it is not unchecked.

If a cast to a reference type is not a compile-time error, there are several cases:

  • The cast is statically known to be correct.

    No run-time action is performed for such a cast.

  • The cast is a completely unchecked cast.

    No run-time action is performed for such a cast.

  • The cast is a partially unchecked cast.

    Such a cast requires a run-time validity check. The check is performed as if the cast had been a checked cast between |S| and |T|, as described below.

  • The cast is a checked cast.

    Such a cast requires a run-time validity check. If the value at run time is null, then the cast is allowed. Otherwise, let R be the class of the object referred to by the run-time reference value, and let T be the erasure (§4.6) of the type named in the cast operator. A cast conversion must check, at run time, that the class R is assignment compatible with the type T, via the algorithm in §5.5.3.

    Note that R cannot be an interface when these rules are first applied for any given cast, but R may be an interface if the rules are applied recursively because the run-time reference value may refer to an array whose element type is an interface type.

4.8 Raw Types

参考地址:https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8

The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.

To make sure that potential violations of the typing rules are always flagged, some accesses to members of a raw type will result in compile-time unchecked warnings. The rules for compile-time unchecked warnings when accessing members or constructors of raw types are as follows:

  • At an assignment to a field: if the type of the left-hand operand is a raw type, then a compile-time unchecked warning occurs if erasure changes the field's type.

  • At an invocation of a method or constructor: if the type of the class or interface to search (§15.12.1) is a raw type, then a compile-time unchecked warning occurs if erasure changes any of the formal parameter types of the method or constructor.

  • No compile-time unchecked warning occurs for a method call when the formal parameter types do not change under erasure (even if the result type and/or throwsclause changes), for reading from a field, or for a class instance creation of a raw type.

Note that the unchecked warnings above are distinct from the unchecked warnings possible from unchecked conversion (§5.1.9), casts (§5.5.2), method declarations (§8.4.1, §8.4.8.3, §8.4.8.4, §9.4.1.2), and variable arity method invocations (§15.12.4.2).

The warnings here cover the case where a legacy consumer uses a generified library. For example, the library declares a generic class Foo<T extends String> that has a field f of type Vector<T>, but the consumer assigns a vector of integers to e.f where e has the raw type Foo. The legacy consumer receives a warning because it may have caused heap pollution (§4.12.2) for generified consumers of the generified library.

(Note that the legacy consumer can assign a Vector<String> from the library to its own Vector variable without receiving a warning. That is, the subtyping rules (§4.10.2) of the Java programming language make it possible for a variable of a raw type to be assigned a value of any of the type's parameterized instances.)

The warnings from unchecked conversion cover the dual case, where a generified consumer uses a legacy library. For example, a method of the library has the raw return type Vector, but the consumer assigns the result of the method invocation to a variable of type Vector<String>. This is unsafe, since the raw vector might have had a different element type than String, but is still permitted using unchecked conversion in order to enable interfacing with legacy code. The warning from unchecked conversion indicates that the generified consumer may experience problems from heap pollution at other points in the program.

例1:

class Cell<E> {
    E value;

    Cell(E v)     { value = v; }
    E get()       { return value; }
    void set(E v) { value = v; }

    public static void main(String[] args) {
        Cell x = new Cell<String>("abc"); // unchecked warning
        System.out.println(x.value);  // OK, has type Object
        System.out.println(x.get());  // OK, has type Object
        x.set("def");                 // unchecked warning
    }
}

Cell x  = new Cell<String>("abc")出现非检查警告:

At an assignment to a field: if the type of the left-hand operand is a raw type, then a compile-time unchecked warning occurs if erasure changes the field's type.

x.set("def")出现非检查警告:

At an invocation of a method or constructor: if the type of the class or interface to search (§15.12.1) is a raw type, then a compile-time unchecked warning occurs if erasure changes any of the formal parameter types of the method or constructor.

例2:

import java.util.*;
class NonGeneric {
    Collection<Number> myNumbers() { return null; }
}

abstract class RawMembers<T> extends NonGeneric implements Collection<String> {
    static Collection<NonGeneric> cng =  new ArrayList<NonGeneric>();

    public static void main(String[] args) {
        RawMembers rw = null;
        Collection<Number> cn = rw.myNumbers();     // OK
        Iterator<String> is = rw.iterator();        // Unchecked warning
        Collection<NonGeneric> cnn = rw.cng;      // OK, static member
    }
}

Collection<Number> cn = rw.myNumbers();没有出现警告:

No compile-time unchecked warning occurs for a method call when the formal parameter types do not change under erasure (even if the result type and/or throwsclause changes), for reading from a field, or for a class instance creation of a raw type.

In this program, RawMembers<T> inherits the method:

Iterator<String> iterator()

from the Collection<String> superinterface. However, the type RawMembers inherits iterator() from the erasure of Collection<String>, which means that the return type of iterator() is the erasure of Iterator<String>, Iterator.

As a result, the attempt to assign to rw.iterator() requires an unchecked conversion (§5.1.9) from Iterator to Iterator<String>, causing an unchecked warning to be issued.

In contrast, the static member cng retains its full parameterized type even when accessed through a object of raw type. (Note that access to a static member through an instance is considered bad style and is to be discouraged.) The member myNumbers is inherited from the NonGeneric class (whose erasure is also NonGeneric) and so retains its full parameterized type.

Raw types are closely related to wildcards. Both are based on existential types. Raw types can be thought of as wildcards whose type rules are deliberately unsound, to accommodate interaction with legacy code. Historically, raw types preceded wildcards; they were first introduced in GJ, and described in the paper Making the future safe for the past: Adding Genericity to the Java Programming Language by Gilad Bracha, Martin Odersky, David Stoutamire, and Philip Wadler, in Proceedings of the ACM Conference on Object-Oriented Programming, Systems, Languages and Applications (OOPSLA 98), October 1998.

  

  

  

the unchecked warnings的更多相关文章

  1. Effective Java 24 Eliminate unchecked warnings

    Note Eliminate every unchecked warning that you can. Set<Lark> exaltation = new HashSet(); The ...

  2. Java Generics and Collections-8.1

    8.1 Take Care when Calling Legacy Code 通常,泛型都是在编译时检查的,而不是运行时.便意识检查可以提早通知错误,而不至于到运行时才出问题. 但有时后编译时检查不一 ...

  3. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  4. Java1.5泛型指南中文版(Java1.5 Generic Tutorial)

    Java1.5泛型指南中文版(Java1.5 Generic Tutorial) 英文版pdf下载链接:http://java.sun.com/j2se/1.5/pdf/generics-tutori ...

  5. java注解学习(1)注解的作用和三个常用java内置注解

    今天,记录一下自己学习的关于注解方面的知识. Annotation是从JDK5.0开始引入的新技术 Annotation的作用: -不是程序本身,可以对程序做出解释(这一点和注释没什么区别) -可以被 ...

  6. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  7. 为什么 Java ArrayList.toArray(T[]) 方法的参数类型是 T 而不是 E ?

    前两天给同事做 code review,感觉自己对 Java 的 Generics 掌握得不够好,便拿出 <Effective Java>1 这本书再看看相关的章节.在 Item 24:E ...

  8. 【Effective Java】阅读

    Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...

  9. 注解Annotation原理详解及其应用示例

    一.什么是注解 注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进 ...

随机推荐

  1. 关于:Warning: skipping non-radio button in group的处理方法整理

    下面讲的是一个意思: The problem is that the next control in the tab order following the last radio button of ...

  2. user_mongo_in_a_docker_and_dump_database

    使用 mongo docker 镜像 使用 mongo 镜像是很方便的,直接使用官方镜像就好了,为了今后更方便使用,这里给出依据 restheart-docker 中的 docker-compose. ...

  3. Delphi 文件拷贝

    function DoCopyDir(sDirName:String;sToDirName:String):Boolean;var hFindFile:Cardinal; t,tfile:String ...

  4. BFC开启条件

    当元素CSS属性设置了下列之一时,即可创建一个BFC: float:left|right position:absolute|fixed display: table-cell|table-capti ...

  5. mybatis 使用tips - 使用多个参数

    执行如下命令: mvn -Dmybatis.generator.overwrite=true mybatis-generator:generate 可以使用mybatis generator myba ...

  6. pycharm中安装可以贴图片的Markdown插件

    方法一:(测试成功) 先安装官方推荐的Markdown support插件,再安装Paste images into MarkDown 如果Paste images into MarkDown插件在线 ...

  7. 目前主流的四大浏览器内核Trident、Gecko、WebKit以及Presto

    “浏览器内核”主要指渲染引擎(Rendering Engine),负责解析网页语法(如HTML.JavaScript)并渲染.展示网页.因此,所谓的浏览器内核通常也就是指浏览器所采用的渲染引擎,渲染引 ...

  8. ADO.NET批量添加数据到SQL Server—BulkCopy使用指南

    BulkCopy位于System.Data.SqlClient命名空间,允许你使用其他源的数据有效地批量加载 SQL Server 表. 属性: BatchSize :每个批处理中的行数. 在每个批处 ...

  9. NPOI+Json文件解析Excel

    记点笔记,加深印象!最近有个导入Excel工能需要完成,Excel列名是中文的,导入Excel我用的NPOI插件,如果不对Excel做解析,列名有可能会给我带来一些字符方面的麻烦,于是想到了一个比较l ...

  10. Spring @SCHEDULED(CRON = "0 0 * * * ?")实现定时任务

    Spring配置文件xmlns加入 xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocati ...