⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 5.doc.html

📁 java语言规范
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<html>
<head>
<title>The Java Language Specification Conversions and Promotions</title>
</head>
<body BGCOLOR=#eeeeff text=#000000 LINK=#0000ff VLINK=#000077 ALINK=#ff0000>
 
<a href="index.html">Contents</a> | <a href="4.doc.html">Prev</a> | <a href="6.doc.html">Next</a> | <a href="j.index.doc1.html">Index</a>
<hr><br>
 
<a name="44342"></a>
<p><strong>
CHAPTER 5 </strong></p>
<a name="27529"></a>
<h1>Conversions and Promotions</h1>
<hr><p>
<a name="25009"></a>
Every Java expression has a type that can be deduced from the structure of the 
expression and the types of the literals, variables, and methods mentioned in the 
expression. It is possible, however, to write an expression in a context where the 
type of the expression is not appropriate. In some cases, this leads to an error at 
compile time; for example, if the expression in an <code>if</code> statement <a href="14.doc.html#5991">(&#167;14.8)</a> has any 
type other than <code>boolean</code>, a compile-time error occurs. In other cases, the context 
may be able to accept a type that is related to the type of the expression; as a convenience,
rather than requiring the programmer to indicate a type conversion 
explicitly, the Java language performs an implicit <i>conversion</i> from the type of the 
expression to a type acceptable for its surrounding context.
<p><a name="25037"></a>
A specific conversion from type <i>S</i> to type <i>T</i> allows an expression of type <i>S</i> to be treated at compile time as if it had type <i>T</i> instead. In some cases this will require a corresponding action at run time to check the validity of the conversion or to translate the run-time value of the expression into a form appropriate for the new type <i>T</i>. For example:<p>
<ul><a name="25041"></a>
<li>A conversion from type <code>Object</code> <a href="javalang.doc1.html#46442">(&#167;20.1)</a> to type <code>Thread</code> <a href="javalang.doc18.html#2658">(&#167;20.20)</a> requires a run-time check to make sure that the run-time value is actually an instance of class <code>Thread</code> or one of its subclasses; if it is not, an exception is thrown.
<a name="25042"></a>
<li>A conversion from type <code>Thread</code> to type <code>Object</code> requires no run-time action; <code>Thread</code> is a subclass of <code>Object</code>, so any reference produced by an expression of type <code>Thread</code> is a valid reference value of type <code>Object</code>.
<a name="25043"></a>
<li>A conversion from type <code>int</code> to type <code>long</code> requires run-time sign-extension of a 32-bit integer value to the 64-bit <code>long</code> representation. No information is lost.
<a name="25044"></a>
<li>A conversion from type <code>double</code> to type <code>long</code> requires a nontrivial translation from a 64-bit floating-point value to the 64-bit integer representation. Depending on the actual run-time value, information may be lost.
</ul><a name="24996"></a>
In every conversion context, only certain specific conversions are permitted. The specific conversions that are possible in Java are grouped for convenience of description into several broad categories:<p>
<ul><a name="25070"></a>
<li>Identity conversions
<a name="25071"></a>
<li>Widening primitive conversions
<a name="25072"></a>
<li>Narrowing primitive conversions
<a name="25073"></a>
<li>Widening reference conversions
<a name="25086"></a>
<li>Narrowing reference conversions
<a name="25087"></a>
<li>String conversions
</ul><a name="24995"></a>
There are five <i>conversion contexts</i> in which conversion of Java expressions may occur. Each context allows conversions in some of the categories named above but not others. The term "conversion" is also used to describe the process of choosing a specific conversion for such a context. For example, we say that an expression that is an actual argument in a method invocation is subject to "method invocation conversion," meaning that a specific conversion will be implicitly chosen for that expression according to the rules for the method invocation argument context.<p>
<a name="25089"></a>
One conversion context is the operand of a numeric operator such as <code>+</code> or <code>*</code>. The conversion process for such operands is called <i>numeric promotion</i>. Promotion is special in that, in the case of binary operators, the conversion chosen for one operand may depend in part on the type of the other operand expression.<p>
<a name="174138"></a>
This chapter first describes the six categories of conversions <a href="5.doc.html#170671">(&#167;5.1)</a>, including the special conversions to <code>String</code> allowed for the string concatenation operator <code>+</code>. Then the five conversion contexts are described:<p>
<ul><a name="25117"></a>
<li>Assignment conversion (<a href="5.doc.html#170768">&#167;5.2</a>, <a href="15.doc.html#5281">&#167;15.25</a>) converts the type of an expression to the type of a specified variable. The conversions permitted for assignment are limited in such a way that assignment conversion never causes an exception.
<a name="52883"></a>
<li>Method invocation conversion (<a href="5.doc.html#12687">&#167;5.3</a>, <a href="15.doc.html#41147">&#167;15.8</a>, <a href="15.doc.html#20448">&#167;15.11</a>) is applied to each argument in a method or constructor invocation and, except in one case, performs the same conversions that assignment conversion does. Method invocation conversion never causes an exception.
<a name="25151"></a>
<li>Casting conversion <a href="5.doc.html#176921">(&#167;5.4)</a> converts the type of an expression to a type explicitly specified by a cast operator <a href="15.doc.html#238146">(&#167;15.15)</a>. It is more inclusive than assignment or method invocation conversion, allowing any specific conversion other than a string conversion, but certain casts to a reference type may cause an exception at run time.
<a name="25179"></a>
<li>String conversion (<a href="5.doc.html#176921">&#167;5.4</a>, <a href="15.doc.html#39990">&#167;15.17.1</a>) allows any type to be converted to type <code>String</code>.
<a name="52885"></a>
<li>Numeric promotion <a href="5.doc.html#26917">(&#167;5.6)</a> brings the operands of a numeric operator to a common type so that an operation can be performed.
</ul><a name="27513"></a>
Here are some examples of the various contexts for conversion:<p>
<pre><a name="27514"></a>
class Test {			
<a name="174326"></a>
	public static void main(String[] args) {
<a name="26212"></a>
		// Casting conversion <a href="5.doc.html#176921">(&#167;5.4)</a> of a float literal to
<a name="26213"></a>		// type int. Without the cast operator, this would
<a name="26214"></a>		// be a compile-time error, because this is a
<a name="26218"></a>		// narrowing conversion <a href="5.doc.html#175672">(&#167;5.1.3)</a>:
<a name="26219"></a>		int i = (int)12.5f;
<br><a name="26266"></a>
		// String conversion <a href="5.doc.html#176921">(&#167;5.4)</a> of i's int value:
<a name="26220"></a>		System.out.println("(int)12.5f==" + i);
<br><a name="26225"></a>
		// Assignment conversion <a href="5.doc.html#170768">(&#167;5.2)</a> of i's value to type
<a name="26229"></a>		// float. This is a widening conversion <a href="5.doc.html#25222">(&#167;5.1.2)</a>:
<a name="26230"></a>		float f = i;
<br><a name="26272"></a>
		// String conversion of f's float value:
<a name="26231"></a>		System.out.println("after float widening: " + f);
<br><a name="26236"></a>
		// Numeric promotion <a href="5.doc.html#26917">(&#167;5.6)</a> of i's value to type
<a name="26237"></a>		// float. This is a binary numeric promotion.
<a name="26238"></a>		// After promotion, the operation is float*float:
<a name="26239"></a>		System.out.print(f);
<a name="26240"></a>		f = f * i;
<br><a name="26284"></a>
		// Two string conversions of i and f:
<a name="26241"></a>		System.out.println("*" + i + "==" + f);
<br><a name="26246"></a>
		// Method invocation conversion <a href="5.doc.html#12687">(&#167;5.3)</a> of f's value
<a name="26247"></a>		// to type double, needed because the method Math.sin
<a name="26248"></a>		// accepts only a double argument:
<a name="26249"></a>		double d = Math.sin(f);
<br><a name="26286"></a>
		// Two string conversions of f and d:
<a name="26250"></a>		System.out.println("Math.sin(" + f + ")==" + d);
<br><a name="26251"></a>	}
<br><a name="26252"></a>}
</pre><a name="26253"></a>
which produces the output:
<p><pre><a name="26254"></a>
(int)12.5f==12
<a name="26255"></a>after float widening: 12.0
<a name="26256"></a>12.0*12==144.0
<a name="26202"></a>Math.sin(144.0)==-0.49102159389846934
</pre><a name="170671"></a>
<h2>5.1    Kinds of Conversion</h2>
<a name="25201"></a>
Specific type conversions in Java are divided into six categories.
<p><a name="25209"></a>
<h3>5.1.1    Identity Conversions</h3>
<a name="25210"></a>
A conversion from a type to that same type is permitted for any type. This may 
seem trivial, but it has two practical consequences. First, it is always permitted for 
an expression to have the desired type to begin with, thus allowing the simply 
stated rule that every expression is subject to conversion, if only a trivial identity 
conversion. Second, it implies that it is permitted for a program to include redundant
cast operators for the sake of clarity.
<p><a name="25214"></a>
The only permitted conversion that involves the type <code>boolean</code> is the identity conversion from <code>boolean</code> to <code>boolean</code>.<p>
<a name="25222"></a>
<h3>5.1.2    Widening Primitive Conversions</h3>
<a name="25224"></a>
The following 19 specific conversions on primitive types are called the <i>widening 
primitive conversions</i>:
<p><ul><a name="25225"></a>
<li><code>byte</code> to <code>short</code>, <code>int</code>, <code>long</code>, <code>float</code>, or <code>double</code>
<a name="25226"></a>
<li><code>short</code> to <code>int</code>, <code>long</code>, <code>float</code>, or <code>double</code>
<a name="25227"></a>
<li><code>char</code> to <code>int</code>, <code>long</code>, <code>float</code>, or <code>double</code>
<a name="25228"></a>
<li><code>int</code> to <code>long</code>, <code>float</code>, or <code>double</code>
<a name="25229"></a>
<li><code>long</code> to <code>float</code> or <code>double</code>
<a name="25230"></a>
<li><code>float</code> to <code>double</code>
</ul><a name="25231"></a>
Widening primitive conversions do not lose information about the overall magnitude of a numeric value. Indeed, conversions widening from an integral type to another integral type and from <code>float</code> to <code>double</code> do not lose any information at all; the numeric value is preserved exactly. Conversion of an <code>int</code> or a <code>long</code> value to <code>float</code>, or of a <code>long</code> value to <code>double</code>, may result in <i>loss of precision</i>-that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode <a href="4.doc.html#9249">(&#167;4.2.4)</a>.<p>
<a name="25237"></a>
A widening conversion of a signed integer value to an integral type <i>T</i><em></em> simply sign-extends the two's-complement representation of the integer value to fill the wider format. A widening conversion of a character to an integral type <i>T</i> zero-extends the representation of the character value to fill the wider format.<p>
<a name="25238"></a>
Despite the fact that loss of precision may occur, widening conversions among primitive types never result in a run-time exception <a href="11.doc.html#44043">(&#167;11)</a>.<p>
<a name="25242"></a>
Here is an example of a widening conversion that loses precision:<p>
<pre><a name="25243"></a>
class Test {
<a name="25244"></a>	public static void main(String[] args) {
<a name="25245"></a>		int big = 1234567890;
<a name="25246"></a>		float approx = big;
<a name="25247"></a>		System.out.println(big - (int)approx);
<a name="25248"></a>	}
<a name="25249"></a>}
</pre><a name="25250"></a>
which prints:
<p><pre><a name="25251"></a>-46
</pre><a name="175670"></a>
thus indicating that information was lost during the conversion from type <code>int</code> to 
type <code>float</code> because values of type <code>float</code> are not precise to nine significant digits.
<p><a name="175672"></a>
<h3>5.1.3    Narrowing Primitive Conversions</h3>
<a name="25363"></a>
The following 23 specific conversions on primitive types are called the <i>narrowing</i> 
<i>primitive conversions</i>:
<p><ul><a name="25257"></a>
<li><code>byte</code> to <code>char</code>
<a name="25258"></a>
<li><code>short</code> to <code>byte</code> or <code>char</code>
<a name="25259"></a>
<li><code>char</code> to <code>byte</code> or <code>short</code>
<a name="25260"></a>
<li><code>int</code> to <code>byte</code>, <code>short</code>, or <code>char</code>
<a name="25261"></a>
<li><code>long</code> to <code>byte</code>, <code>short</code>, <code>char</code>, or <code>int</code>
<a name="25262"></a>
<li><code>float</code> to <code>byte</code>, <code>short</code>, <code>char</code>, <code>int</code>, or <code>long</code>
<a name="25263"></a>
<li><code>double</code> to <code>byte</code>, <code>short</code>, <code>char</code>, <code>int</code>, <code>long</code>, or <code>float</code>
</ul><a name="25264"></a>
Narrowing conversions may lose information about the overall magnitude of a numeric value and may also lose precision.<p>
<a name="25265"></a>
A narrowing conversion of a signed integer to an integral type <i>T</i> simply discards all but the <i>n </i>lowest order bits, where <i>n </i>is the number of bits used to represent type <i>T</i>. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.<p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -