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

📄 15.doc.html

📁 java语言规范
💻 HTML
📖 第 1 页 / 共 5 页
字号:
length 10, <img src="15.doc.anc8.gif"> arrays of length 8, and <img src="15.doc.anc9.gif"> arrays of length 
12. This example leaves the fifth dimension, which would be arrays containing the 
actual array elements (references to <code>Age</code> objects), initialized only to null references.
These arrays can be filled in later by other code, such as:
<p><pre><a name="36991"></a>
Age[] Hair = { new Age("quartz"), new Age("topaz") };
<a name="36992"></a>Aquarius[1][9][6][9] = Hair;
</pre><a name="23652"></a>
A multidimensional array need not have arrays of the same length at each level; thus, a triangular matrix may be created by:<p>
<pre><a name="23653"></a>
float triang[][] = new float[100][];
<a name="23654"></a>for (int i = 0; i &lt; triang.length; i++)
<a name="50224"></a>	triang[i] = new float[i+1];
</pre><a name="23655"></a>
There is, however, no way to get this effect with a single creation expression.
<p><a name="23879"></a>
<h3>15.9.2    Example: Array Creation Evaluation Order</h3>
<a name="23883"></a>
In an array creation expression <a href="15.doc.html#46168">(&#167;15.9)</a>, there may be one or more dimension 
expressions, each within brackets. Each dimension expression is fully evaluated 
before any part of any dimension expression to its right.
<p><a name="23510"></a>
Thus:<p>
<pre><a name="23511"></a>
class Test {
<a name="23512"></a>	public static void main(String[] args) {
<a name="23513"></a>		int i = 4;
<a name="23514"></a>		int ia[][] = new int[i][i=3];
<a name="23515"></a>		System.out.println(
<a name="23516"></a>			"[" + ia.length + "," + ia[0].length + "]");
<a name="23517"></a>	}
<a name="23518"></a>}
</pre><a name="23519"></a>
prints:
<p><pre><a name="23520"></a>[4,3]
</pre><a name="23521"></a>
because the first dimension is calculated as <code>4</code> before the second dimension expression
sets <code>i</code> to <code>3</code>.
<p><a name="23522"></a>
If evaluation of a dimension expression completes abruptly, no part of any dimension expression to its right will appear to have been evaluated. Thus, the example: <p>
<pre><a name="23524"></a>
class Test {
<a name="23525"></a>
	public static void main(String[] args) {
<a name="23526"></a>		int[][] a = { { 00, 01 }, { 10, 11 } };
<a name="23527"></a>		int i = 99;
<a name="23528"></a>		try {
<a name="23529"></a>			a[val()][i = 1]++;
<a name="23530"></a>		} catch (Exception e) {
<a name="23531"></a>			System.out.println(e + ", i=" + i);
<a name="23532"></a>		}
<a name="23533"></a>	}
<br><a name="23534"></a>	static int val() throws Exception {
<a name="50226"></a>		throw new Exception("unimplemented");
<a name="50228"></a>	}
<br><a name="23535"></a>}
</pre><a name="23536"></a>
prints:
<p><pre><a name="23537"></a>java.lang.Exception: unimplemented, i=99
</pre><a name="23538"></a>
because the embedded assignment that sets <code>i</code> to <code>1</code> is never executed.
<p><a name="36736"></a>
<h3>15.9.3    Example: Array Creation and Out-of-Memory Detection</h3>
<a name="36885"></a>
If evaluation of an array creation expression finds there is insufficient memory to 
perform the creation operation, then an <code>OutOfMemoryError</code> is thrown. This check 
occurs only after evaluation of all dimension expressions has completed normally.
<p><a name="36744"></a>
So, for example, the test program:<p>
<pre><a name="36800"></a>
class Test {
<a name="36801"></a>	public static void main(String[] args) {
<a name="36802"></a>		int len = 0, oldlen = 0;
<a name="36818"></a>		Object[] a = new Object[0];
<a name="36804"></a>		try {
<a name="238115"></a>			for (;;) {
<a name="238116"></a>				++len;
<a name="238117"></a>				Object[] temp = new Object[oldlen = len];
<a name="238118"></a>				temp[0] = a;
<a name="36823"></a>				a = temp;
<a name="36833"></a>			}
<a name="36807"></a>		} catch (Error e) {
<a name="36808"></a>			System.out.println(e + ", " + (oldlen==len));
<a name="36811"></a>		}
<a name="36812"></a>	}
<a name="36813"></a>}
</pre><a name="36764"></a>
prints:
<p><pre><a name="36765"></a>java.lang.OutOfMemoryError, true
</pre><a name="36901"></a>
because the out-of-memory condition is detected after the argument expression 
<code>oldlen</code> = <code>len</code> is evaluated.
<p><a name="36905"></a>
Compare this to class instance creation expressions <a href="15.doc.html#41147">(&#167;15.8)</a>, which detect the out-of-memory condition before evaluating argument expressions <a href="15.doc.html#36687">(&#167;15.8.2)</a>.<p>
<a name="41267"></a>
<h2>15.10    Field Access Expressions</h2>
<a name="37024"></a>
A field access expression may access a field of an object or array, a reference to 
which is the value of either an expression or the special keyword <code>super</code>. (It is also 
possible to refer to a field of the current instance or current class by using a simple 
name; see <a href="15.doc.html#4984">&#167;15.13.1</a>.)
<p><ul><pre>
<i>FieldAccess:<br>
</i>	<i>Primary</i><code> . </code><i>Identifier<br>
</i>	<code>super . </code><i>Identifier
</i></pre></ul><a name="37051"></a>
The meaning of a field access expression is determined using the same rules as for qualified names <a href="6.doc.html#33916">(&#167;6.6)</a>, but limited by the fact that an expression cannot denote a package, class type, or interface type.<p>
<a name="37055"></a>
<h3>15.10.1    Field Access Using a Primary</h3>
<a name="37056"></a>
The type of the <i>Primary</i> must be a reference type <i>T</i>, or a compile-time error 
occurs. The meaning of the field access expression is determined as follows:
<p><ul><a name="20394"></a>
<li>If the identifier names several accessible member fields of type <i>T</i>, then the field access is ambiguous and a compile-time error occurs.
<a name="37075"></a>
<li>If the identifier does not name an accessible member field of type <i>T</i>, then the field access is undefined and a compile-time error occurs.
<a name="20398"></a>
<li>Otherwise, the identifier names a single accessible member field of type <i>T</i> and the type of the field access expression is the declared type of the field. At run time, the result of the field access expression is computed as follows:
<ul>
<a name="37316"></a>
<li>If the field is <code>static</code>:
<ul>
<a name="37335"></a>
<li>If the field is <code>final</code>, then the result is the value of the specified class variable in the class or interface that is the type of the <i>Primary</i> expression.
<a name="37336"></a>
<li>If the field is not <code>final</code>, then the result is a variable, namely, the specified class variable in the class that is the type of the <i>Primary</i> expression.
</ul>
<a name="37320"></a>
<li>If the field is not <code>static</code>:
<ul>
<a name="37110"></a>
<li>If the value of the <i>Primary</i> is <code>null</code>, then a <code>NullPointerException</code> is thrown.
<a name="20427"></a>
<li>If the field is <code>final</code>, then the result is the value of the specified instance variable in the object referenced by the value of the <i>Primary</i>.
<a name="20400"></a>
<li>If the field is not <code>final</code>, then the result is a variable, namely, the specified instance variable in the object referenced by the value of the <i>Primary</i>.
</ul>
</ul>
</ul><a name="37135"></a>
Note, specifically, that only the type of the <i>Primary</i> expression, not the class of the 
actual object referred to at run time, is used in determining which field to use.
<p><a name="21262"></a>
Thus, the example:<p>
<pre><a name="20890"></a>class S { int x = 0; }
<a name="20893"></a>class T extends S { int x = 1; }
<a name="20896"></a>class Test {
<a name="20897"></a>	public static void main(String[] args) {
</pre><pre><a name="20898"></a>
		T t = new T();
<a name="20899"></a>		System.out.println("t.x=" + t.x + when("t", t));
<a name="20928"></a>
		S s = new S();
<a name="20901"></a>		System.out.println("s.x=" + s.x + when("s", s));
<a name="20902"></a>
		s = t;
<a name="20916"></a>		System.out.println("s.x=" + s.x + when("s", s));
<br><a name="20904"></a>	}
<br><a name="20930"></a>
	static String when(String name, Object t) {
<a name="20931"></a>		return " when " + name + " holds a "
<a name="20959"></a>			+ t.getClass() + " at run time.";
<a name="20932"></a>	}
<a name="20905"></a>}
</pre><a name="20906"></a>
produces the output:
<p><pre><a name="20961"></a>
t.x=1 when t holds a class T at run time.
<a name="20962"></a>s.x=0 when s holds a class S at run time.
<a name="45445"></a>s.x=0 when s holds a class T at run time.
</pre><a name="45446"></a>
The last line shows that, indeed, the field that is accessed does not depend on the 
run-time class of the referenced object; even if <code>s</code> holds a reference to an object of 
class <code>T</code>, the expression <code>s.x</code> refers to the <code>x</code> field of class <code>S</code>, because the type of the 
expression <code>s</code> is <code>S</code>. Objects of class <code>T</code> contain two fields named <code>x</code>, one for class <code>T</code> 
and one for its superclass <code>S</code>.
<p><a name="22264"></a>
This lack of dynamic lookup for field accesses allows Java to run efficiently with straightforward implementations. The power of late binding and overriding is available in Java, but only when instance methods are used. Consider the same example using instance methods to access the fields:<p>
<pre><a name="37188"></a>class S { int x = 0; int z() { return x; } }
<a name="37189"></a>class T extends S { int x = 1; int z() { return x; } }
<a name="37190"></a>class Test {
</pre><pre><a name="37191"></a>
	public static void main(String[] args) {
<a name="37192"></a>		T t = new T();
<a name="37193"></a>		System.out.println("t.z()=" + t.z() + when("t", t));
<a name="37194"></a>		S s = new S();
<a name="37195"></a>		System.out.println("s.z()=" + s.z() + when("s", s));
<a name="37196"></a>		s = t;
<a name="37197"></a>		System.out.println("s.z()=" + s.z() + when("s", s));
<a name="37198"></a>	}
<a name="37199"></a>
	static String when(String name, Object t) {
<a name="37200"></a>		return " when " + name + " holds a "
<a name="37201"></a>			+ t.getClass() + " at run time.";
<a name="37202"></a>	}
<a name="37203"></a>}
</pre><a name="238134"></a>
Now the output is:
<p><pre><a name="37243"></a>

⌨️ 快捷键说明

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