📄 5.doc.html
字号:
<a name="12577"></a> // we cannot be sure they will succeed, depending on
<a name="17240"></a> // the run-time type of p; a run-time check will be
<a name="17245"></a> // necessary for the needed narrowing conversion and
<a name="12579"></a> // must be indicated by including a cast:
<a name="12580"></a> cp = p; // p might be neither a ColoredPoint
<a name="29523"></a> // nor a subclass of ColoredPoint
<a name="12581"></a> c = p; // p might not implement Colorable
<br><a name="12593"></a> }
<br><a name="12594"></a>}
</pre><a name="29746"></a>
Here is another example involving assignment of array objects:
<p><pre><a name="29747"></a>
class Point { int x, y; }
<br><a name="29748"></a>class ColoredPoint extends Point { int color; }
<br><a name="29749"></a>
class Test {
<a name="29750"></a> public static void main(String[] args) {
<a name="29751"></a> long[] veclong = new long[100];
<a name="29752"></a> Object o = veclong; // okay
<a name="29753"></a> Long l = veclong; // compile-time error
<a name="29754"></a> short[] vecshort = veclong; // compile-time error
<a name="29755"></a> Point[] pvec = new Point[100];
<a name="29756"></a> ColoredPoint[] cpvec = new ColoredPoint[100];
<a name="29757"></a> pvec = cpvec; // okay
<a name="50093"></a> pvec[0] = new Point(); // okay at compile time,
<a name="174449"></a> // but would throw an
<a name="174450"></a> // exception at run time
<a name="29758"></a> cpvec = pvec; // compile-time error
<a name="29759"></a> }
<a name="29760"></a>}
</pre><a name="29761"></a>
In this example:
<p><ul><a name="12615"></a>
<li>The value of <code>veclong</code> cannot be assigned to a <code>Long</code> variable, because <code>Long</code> is a class type <a href="javalang.doc7.html#46750">(§20.8)</a> other than <code>Object</code>. An array can be assigned only to a variable of a compatible array type, or to a variable of type <code>Object</code>.
<a name="12616"></a>
<li>The value of <code>veclong</code> cannot be assigned to <code>vecshort</code>, because they are arrays of primitive type, and <code>short</code> and <code>long</code> are not the same primitive type.
<a name="12617"></a>
<li>The value of <code>cpvec</code> can be assigned to <code>pvec</code>,<code></code> because any reference that could be the value of an expression of type <code>ColoredPoint</code> can be the value of a variable of type <code>Point</code>. The subsequent assignment of the new <code>Point</code> to a component of <code>pvec</code> then would throw an <code>ArrayStoreException</code> (if the program were otherwise corrected so that it could be compiled), because a <code>ColoredPoint</code>  array can't have an instance of <code>Point</code> as the value of a component.
<a name="29743"></a>
<li>The value of <code>pvec</code> cannot be assigned to <code>cpvec</code>,<code></code> because not every reference that could be the value of an expression of type <code>ColoredPoint</code> can correctly be the value of a variable of type <code>Point</code>. If the value of <code>pvec</code> at run time were a reference to an instance of <code>Point[]</code>, and the assignment to <code>cpvec</code> were allowed, a simple reference to a component of <code>cpvec</code>, say, <code>cpvec[0]</code>, could return a <code>Point</code>, and a <code>Point</code> is not a <code>ColoredPoint</code>. Thus to allow such an assignment would allow a violation of the type system. A cast may be used (<a href="5.doc.html#176921">§5.4</a>, <a href="15.doc.html#238146">§15.15</a>) to ensure that <code>pvec</code> references a <code>ColoredPoint[]</code>:
</ul><pre><a name="174507"></a>
cpvec = (ColoredPoint[])pvec; // okay, but may throw an
<a name="174508"></a> // exception at run time
</pre><a name="12687"></a>
<h2>5.3 Method Invocation Conversion</h2>
<a name="53171"></a>
<i>Method invocation conversion</i> is applied to each argument value in a method or
constructor invocation (<a href="15.doc.html#41147">§15.8</a>, <a href="15.doc.html#20448">§15.11</a>): the type of the argument expression must
be converted to the type of the corresponding parameter. Method invocation contexts
allow the use of an identity conversion <a href="5.doc.html#25209">(§5.1.1)</a>, a widening primitive conversion
<a href="5.doc.html#25222">(§5.1.2)</a>, or a widening reference conversion <a href="5.doc.html#25215">(§5.1.4)</a>.
<p><a name="26526"></a>
Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion <a href="5.doc.html#170768">(§5.2)</a>. The Java designers felt that including these implicit narrowing conversions would add additional complexity to the overloaded method matching resolution process <a href="15.doc.html#21693">(§15.11.2)</a>. Thus, the example:<p>
<pre><a name="12738"></a>
class Test {
<br><a name="13070"></a> static int m(byte a, int b) { return a+b; }
<br><br><a name="20310"></a> static int m(short a, short b) { return a-b; }
<br><a name="13071"></a> public static void main(String[] args) {
<a name="13072"></a> System.out.println(m(12, 2)); // compile-time error
<a name="20350"></a> }
<br><a name="13077"></a>}
</pre><a name="20230"></a>
causes a compile-time error because the integer literals <code>12</code> and <code>2</code> have type <code>int</code>, so
neither method <code>m</code> matches under the rules of <a href="15.doc.html#21693">(§15.11.2)</a>. A language that included
implicit narrowing of integer constants would need additional rules to resolve
cases like this example.
<p><a name="176921"></a>
<h2>5.4 String Conversion</h2>
<a name="176922"></a>
String conversion applies only to the operands of the binary <code>+</code> operator when one
of the arguments is a <code>String</code>. In this single special case, the other argument to the
<code>+</code> is converted to a <code>String</code>, and a new <code>String</code> which is the concatenation of the
two strings is the result of the <code>+</code>. String conversion is specified in detail within the
description of the string concatenation <code>+</code> operator <a href="15.doc.html#39990">(§15.17.1)</a>.
<p><a name="20232"></a>
<h2>5.5 Casting Conversion</h2>
<a name="20233"></a>
<i>Casting conversion</i> is applied to the operand of a cast operator <a href="15.doc.html#238146">(§15.15)</a>: the type
of the operand expression must be converted to the type explicitly named by the
cast operator. Casting contexts allow the use of an identity conversion <a href="5.doc.html#25209">(§5.1.1)</a>, a
widening primitive conversion <a href="5.doc.html#25222">(§5.1.2)</a>, a narrowing primitive conversion
<a href="5.doc.html#175672">(§5.1.3)</a>, a widening reference conversion <a href="5.doc.html#25215">(§5.1.4)</a>, or a narrowing reference conversion
<a href="5.doc.html#25379">(§5.1.5)</a>. Thus casting conversions are more inclusive than assignment or
method invocation conversions: a cast can do any permitted conversion other than
a string conversion.
<p><a name="175729"></a>
Some casts can be proven incorrect at compile time; such casts result in a compile-time error.<p>
<a name="175719"></a>
A value of a primitive type can be cast to another primitive type by identity conversion, if the types are the same, or by a widening primitive conversion or a narrowing primitive conversion.<p>
<a name="175724"></a>
A value of a primitive type cannot be cast to a reference type by casting conversion, nor can a value of a reference type be cast to a primitive type.<p>
<a name="175725"></a>
The remaining cases involve conversion between reference types. The detailed rules for compile-time correctness checking of a casting conversion of a value of compile-time reference type <i>S</i><i></i> (source) to a compile-time reference type <i>T</i><em></em> (target) are as follows:<p>
<ul><a name="27459"></a>
<li>If <i>S</i><i></i> is a class type:
<ul>
<a name="27460"></a>
<li>If <i>T</i><em></em> is a class type, then <i>S</i><i></i> and <i>T</i><em></em> must be related classes-that is, <i>S</i><em></em> and <i>T</i><em></em> must be the same class, or <i>S</i><i></i> a subclass of <i>T</i><em>,</em> or <i>T</i><em></em> a subclass of <i>S</i><em></em>; otherwise a compile-time error occurs.
<a name="27461"></a>
<li>If <i>T</i><em></em> is an interface type:
<ul>
<a name="26664"></a>
<li>If <i>S</i><i></i> is not a <code>final</code> class <a href="8.doc.html#21613">(§8.1.2)</a>, then the cast is always correct at compile time (because even if <i>S</i><i></i> does not implement <i>T</i>, a subclass of <i>S</i><i></i> might).
<a name="26668"></a>
<li>If <i>S</i><i></i> is a <code>final</code> class <a href="8.doc.html#21613">(§8.1.2)</a>, then <i>S</i><i></i> must implement <i>T</i>,<em></em> or a compile-time error occurs.
</ul>
<a name="27505"></a>
<li>If <i>T</i><em></em> is an array type, then <i>S</i><i></i> must be the class <code>Object</code>, or a compile-time error occurs.
</ul>
<a name="27506"></a>
<li>If <i>S</i><i></i> is an interface type:
<ul>
<a name="27507"></a>
<li>If <i>T</i><em></em> is a class type that is not <code>final</code> <a href="8.doc.html#21613">(§8.1.2)</a>, then the cast is always correct at compile time (because even if <i>T</i><em></em> does not implement <i>S</i>, a subclass of <i>T</i><em></em> might).
<a name="27508"></a>
<li>If <i>T</i><em></em> is a class type that is <code>final</code> <a href="8.doc.html#21613">(§8.1.2)</a>, then <i>T</i><em></em> must implement <i>S</i>,<i></i> or a compile-time error occurs.
<a name="45656"></a>
<li>If <i>T</i><em></em> is an interface type and if <i>T</i><em></em> and <i>S</i><i></i> contain methods with the same signature <a href="8.doc.html#38649">(§8.4.2)</a> but different return types, then a compile-time error occurs.
</ul>
<a name="53974"></a>
<li>If <i>S</i><em></em> is an array type <i>SC</i><code>[]</code>, that is, an array of components of type <i>SC</i><em></em>:
<ul>
<a name="53981"></a>
<li>If <i>T</i><em></em> is a class type, then if <i>T</i><em></em> is not <code>Object</code>, then a compile-time error occurs (because <code>Object</code> is the only class type to which arrays can be assigned).
<a name="28948"></a>
<li>If <i>T</i><em></em> is an interface type, then a compile-time error occurs unless <i>T</i> is the interface type <code>Cloneable</code>, the only interface implemented by arrays.
<a name="28949"></a>
<li>If <i>T</i><em></em> is an array type <i>TC</i><code>[]</code>, that is, an array of components of type <i>TC</i>, then a compile-time error occurs unless one of the following is true:
<ul>
<a name="176094"></a>
<li><i>TC</i><em></em> and <i>SC</i><em></em> are the same primitive type.
<a name="176095"></a>
<li><i>TC</i><em></em> and <i>SC</i><em></em> are reference types and type <i>SC</i><em></em> can be cast to <i>TC</i><em></em> by a recursive application of these compile-time rules for casting.
</ul>
</ul>
</ul><a name="174613"></a>
See <a href="8.doc.html#3857">§8</a> for the detailed specifications of classes, <a href="9.doc.html#238678">§9</a> for interfaces, and <a href="10.doc.html#27803">§10</a> for
arrays.
<p><a name="27456"></a>
If a cast to a reference type is not a compile-time error, there are two cases:<p>
<ul><a name="26702"></a>
<li>The cast can be determined to be correct at compile time. A cast from the compile-time type <i>S</i><i></i> to compile-time type <i>T</i><em></em> is correct at compile time if and only if <i>S</i><i></i> can be converted to <i>T</i><em></em> by assignment conversion <a href="5.doc.html#170768">(§5.2)</a>.
<a name="26706"></a>
<li>The cast requires a run-time validity check. If the value at run time is <code>null</code>, then the cast is allowed. Otherwise, let <i>R</i> be the class of the object referred to by the run-time reference value, and let <i>T</i><em></em> be the type named in the cast operator. A cast conversion must check, at run time, that the class <i>R</i> is assignment compatible with the type <i>T</i>, using the algorithm specified in <a href="5.doc.html#170768">§5.2</a> but using the class <i>R</i> instead of the compile-time type <i>S</i><em></em> as specified there. (Note that <i>R</i> cannot be an interface when these rules are first applied for any given cast, but <i>R</i> may be an interface if the rules are applied recursively because the run-time reference value refers to an array whose element type is an interface type.) This modified algorithm is shown here:
<ul>
<a name="29070"></a>
<li>If <i>R</i> is an ordinary class (not an array class):
<ul>
<a name="29074"></a>
<li>If <i>T</i><em></em> is a class type, then <i>R</i><em></em> must be either the same class <a href="4.doc.html#52197">(§4.3.4)</a> as <i>T</i><em></em> or a subclass of <i>T</i>, or a run-time exception is thrown.
<a name="29084"></a>
<li>If <i>T</i><em></em> is an interface type, then <i>R</i> must implement <a href="8.doc.html#34031">(§8.1.4)</a> interface <i>T</i>, or a run-time exception is thrown.
<a name="29085"></a>
<li>If <i>T</i><em></em> is an array type, then a run-time exception is thrown.
</ul>
<a name="174679"></a>
<li>If <i>R</i><i></i> is an interface:
<ul>
<a name="174686"></a>
<li>If <i>T</i> is a class type, then <i>T</i> must be <code>Object</code> (<a href="4.doc.html#11055">§4.3.2</a>, <a href="javalang.doc1.html#46442">§20.1</a>), or a run-time exception is thrown.
<a name="174687"></a>
<li>If <i>T</i> is an interface type, then <i>R</i> must be either the same interface as <i>T</i> or a subinterface of <i>T</i>,<i></i> or a run-time exception is thrown.
<a name="174682"></a>
<li>If <i>T</i> is an array type, then a run-time exception is thrown.
</ul>
<a name="29102"></a>
<li>If <i>R</i> is a class representing an array type <i>RC</i><code>[]</code>-that is, an array of components of type <i>RC</i><em>:</em>
<ul>
<a name="29109"></a>
<li>If <i>T</i><em></em> is a class type, then <i>T</i><em></em> must be <code>Object</code> (<a href="4.doc.html#11055">§4.3.2</a>, <a href="javalang.doc1.html#46442">§20.1</a>), or a run-time exception is thrown.
<a name="29110"></a>
<li>If <i>T</i><em></em> is an interface type, then a run-time exception is thrown unless <i>T</i> is the interface type <code>Cloneable</code>, the only interface implemented by arrays (this case could slip past the compile-time checking if, for example, a reference to an array were stored in a variable of type <code>Object</code>).
<a name="29114"></a>
<li>If <i>T</i><em></em> is an array type <i>TC</i><em></em><code>[]</code>, that is, an array of components of type <i>TC</i><em>,</em> then a run-time exception is thrown unless one of the following is true:
<ul>
<a name="29118"></a>
<li><i>TC</i><em></em> and <i>RC</i><em></em> are the same primitive type.
<a name="29119"></a>
<li><i>TC</i><em></em> and <i>RC</i><em></em> are reference types and type <i>RC</i><em></em> can be cast to <i>TC</i><em></em> by a recursive application of these run-time rules for casting.
</ul>
</ul>
</ul>
</ul><a name="13146"></a>
If a run-time exception is thrown, it is a <code>ClassCastException</code> (<a href="11.doc.html#44287">§11.5.1.1</a>,
<a href="javalang.doc20.html#46198">§20.22</a>).
<p><a name="176364"></a>
Here are some examples of casting conversions of reference types, similar to the example in <a href="5.doc.html#170768">§5.2</a>:<p>
<pre><a name="29290"></a>
public class Point { int x, y; }
<br><a name="29434"></a>public interface Colorable { void setColor(int color); }
<br><a name="29291"></a>
public class ColoredPoint extends Point implements Colorable
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -