UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

30 lines (29 loc) 6.48 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Casts</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Casts"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-8-SECT-5"/>Casts</h1></div></div></div><p><a id="idx10390" class="indexterm"/> <a id="idx10404" class="indexterm"/>We’ve now talked about relationships between generic types and even between generic types and raw types. But we haven’t brought up the concept of a cast yet. No cast was necessary when we interchanged generics with their raw types. Instead, we just crossed a line that triggers unchecked warnings from the compiler:</p><a id="I_8_tt417"/><pre class="programlisting"> <code class="n">List</code> <code class="n">list</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;();</code> <code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">dl</code> <code class="o">=</code> <code class="n">list</code><code class="o">;</code> <code class="c1">// unchecked warning</code></pre><p>Normally, we use a cast in Java to work with two types that could be assignable. For example, we could attempt to cast an <code class="literal">Object</code> to a <code class="literal">Date</code> because it is plausible that the <code class="literal">Object</code> is a <code class="literal">Date</code> value. The cast then performs the check at runtime to see if we are correct. Casting between unrelated types is a compile-time error. For example, we can’t even try to cast an <code class="literal">Integer</code> to a <code class="literal">String</code>. Those types have no inheritance relationship. What about casts between compatible generic types?</p><a id="I_8_tt418"/><pre class="programlisting"> <code class="n">Collection</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">cd</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;();</code> <code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">ld</code> <code class="o">=</code> <code class="o">(</code><code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;)</code><code class="n">cd</code><code class="o">;</code> <code class="c1">// Ok!</code></pre><p>This code snippet shows a valid cast from a more general <code class="literal">Collection&lt;Date&gt;</code> to a <code class="literal">List&lt;Date&gt;</code>. The cast is plausible here because a <code class="literal">Collection&lt;Date&gt;</code> is assignable from and could actually be a <code class="literal">List&lt;Date&gt;</code>. Similarly, the following cast catches our mistake where we have aliased a <code class="literal">TreeSet&lt;Date&gt;</code> as a <code class="literal">Collection&lt;Date&gt;</code> and tried to cast it to a <code class="literal">List&lt;Date&gt;</code>:</p><a id="I_8_tt419"/><pre class="programlisting"> <code class="n">Collection</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">cd</code> <code class="o">=</code> <code class="k">new</code> <code class="n">TreeSet</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;();</code> <code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">ld</code> <code class="o">=</code> <code class="o">(</code><code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;)</code><code class="n">cd</code><code class="o">;</code> <code class="c1">// Runtime ClassCastException!</code> <code class="n">ld</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">Date</code><code class="o">()</code> <code class="o">);</code></pre><p>There is one case where casts are not effective with generics, however, and that is when we are trying to differentiate the types based on their parameter types:</p><a id="I_8_tt420"/><pre class="programlisting"> <code class="n">Object</code> <code class="n">o</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">&lt;</code><code class="n">String</code><code class="o">&gt;();</code> <code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">ld</code> <code class="o">=</code> <code class="o">(</code><code class="n">List</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;)</code><code class="n">o</code><code class="o">;</code> <code class="c1">// unchecked warning, ineffective</code> <code class="n">Date</code> <code class="n">d</code> <code class="o">=</code> <code class="n">ld</code><code class="o">.</code><code class="na">get</code><code class="o">(</code><code class="mi">0</code><code class="o">);</code> <code class="c1">// unsafe at runtime, implicit cast may fail</code></pre><p>Here, we aliased an <code class="literal">ArrayList&lt;String&gt;</code> as a plain <code class="literal">Object</code>. Next, we cast it to a <code class="literal">List&lt;Date&gt;</code>. Unfortunately, Java does not know the difference between a <code class="literal">List&lt;String&gt;</code> and a <code class="literal">List&lt;Date&gt;</code> at runtime, so the cast is fruitless. The compiler warns us of this by generating an unchecked warning at the location of the cast; we should be aware that when we try to use the cast object later, we might find out that it is incorrect. Casts on generic types are ineffective at runtime because of erasure and the lack of type information.<a id="I_indexterm8_id709127" class="indexterm"/><a id="I_indexterm8_id709134" class="indexterm"/></p></div></body></html>