Spec-Zone .ru
спецификации, руководства, описания, API
Содержание | Предыдущий | Следующий | Индекс

ГЛАВА 16

Определенное Присвоение


У каждой локальной переменной должно быть определенно присвоенное значение, когда любой доступ его значения происходит. Доступ к его значению состоит из простого имени переменной, происходящей где угодно в выражении за исключением левого операнда простого оператора присваивания =.

Компилятор Java должен выполнить определенный консервативный анализ потоков, чтобы удостовериться, что для каждого доступа локальной переменной локальная переменная определенно присваивается перед доступом; иначе ошибка времени компиляции должна произойти.

Остаток от этой главы посвящается точному объяснению слов, "определенно присвоенных прежде". Идея состоит в том, что присвоение на локальную переменную должно произойти на каждом возможном пути выполнения к доступу с начала конструктора, метода, или статического инициализатора, который содержит доступ. Анализ принимает во внимание структуру операторов и выражений; это также обеспечивает специальный режим операторов выражения !, &&, ||, и ? :, операторы &, |, ^, ==, и != с boolean операнды, и оцененные булевской переменной константные выражения. Например, компилятор Java распознает это k определенно присваивается перед его доступом (как параметр вызова метода) в коде:


{
	int k;
	if (v > 0 && (k = System.in.read()) >= 0)
		System.out.println(k);
}
потому что доступ происходит только если значение выражения:

v > 0 && (k = System.in.read()) >= 0
истина, и значение может быть true только если присвоение на k выполняется (более должным образом, оценивается). Точно так же компилятор Java распознает что в коде:


{
	int k;
	while (true) {
		k = n;
		if (k >= 5) break;
		n = 6;
	}
	System.out.println(k);
}
переменная k определенно присваивается while оператор, потому что выражение условия true никогда не имеет значение false, так только break оператор может вызвать while оператор, чтобы обычно завершаться, и k определенно присваивается перед break оператор.

За исключением специального режима определенных булевых операторов и оцененных булевской переменной константных выражений, значения выражений не принимаются во внимание в анализе потоков. Например, компилятор Java должен произвести ошибку времени компиляции для кода:


{
	int k;
	int n = 5;
	if (n > 2)
		k = 3;
	System.out.println(k);					// k is not "definitely assigned" before this
}
даже при том, что значение n известен во время компиляции, и в принципе можно быть известно во время компиляции что присвоение на k будет всегда выполняться (более должным образом, оцениваться). Компилятор Java должен работать согласно правилам, размеченным в этом разделе. Правила распознают только константные выражения; в этом примере, выражении n > 2 не константное выражение как определено в §15.27.

Как другой пример, компилятор Java примет код:


void flow(boolean flag) {
	int k;
	if (flag)
		k = 3;
	else
		k = 4;
	System.out.println(k);
}
до определенного присвоения k затрагивается, потому что правила, обрисованные в общих чертах в этом разделе, позволяют этому говорить это k присваивается независимо от того, является ли флаг true или false. Но правила не принимают изменение:


void flow(boolean flag) {
	int k;
	if (flag)
		k = 3;
	if (!flag)
		k = 4;
	System.out.println(k); 					// k is not "definitely assigned" before here
}
и так компиляция этой программы должна заставить ошибку времени компиляции происходить.

Чтобы точно определить все случаи определенного присвоения, правила в этом разделе определяют два технических термина:

Чтобы определить оцененные булевской переменной выражения, последнее понятие усовершенствовано в два случая:

Здесь, когда истина и когда ложь обращаются к значению выражения. Например, локальная переменная k определенно присваивается значение после оценки выражения

a && ((k=m) > 5)
когда выражение true но не, когда выражение false (потому что, если a false, тогда присвоение на k не выполняется (более должным образом, оценивается)).

Оператор "V определенно присваивается, после X" (то, где V локальная переменная и X, является оператором или выражением) означает "V, определенно присваивается после X, если X обычно завершается". Если X завершается резко, присвоение, возможно, не произошло, и правила, утвержденные здесь, принимают это во внимание. Специфическое последствие этого определения - то, что "V определенно присваивается после break;"всегда истина! Поскольку a break оператор никогда обычно не завершается, это вырождено истинно, что V был присвоен значение если break оператор обычно завершается.

Чтобы сократить правила, общепринятое сокращение "эквивалентность" используется, чтобы означать "если и только если".

Позвольте V быть локальной переменной. Позвольте a, b, c, и e быть выражениями. Позвольте S и T быть операторами.

16.1 Определенное Присвоение и Выражения

16.1.1 Булевы Константные выражения

V определенно присваивается после любого константного выражения, значение которого true когда ложь. V определенно присваивается после любого константного выражения, значение которого false когда истина.

Константное выражение, значение которого true никогда не имеет значение false, и константное выражение, значение которого false никогда не имеет значение true, эти определения вырождено удовлетворяются. Они полезны в анализе выражений, включающих булевы операторы &&, ||, и ! (§16.1.3, §16.1.4, §16.1.5).

16.1.2 Оцененные булевской переменной Выражения

Для каждого оцененного булевской переменной выражения:

16.1.3 Булев оператор &&

16.1.4 Булев оператор ||

16.1.5 Булев оператор !

16.1.6 Булев оператор &

16.1.7 Булев оператор |

16.1.8 Булев оператор ^

16.1.9 Булев оператор ==

16.1.10 Булев оператор !=

Правила для a != b идентичны правилам для a ^ b (§16.1.8).

16.1.11 Булев оператор ? :

Предположите, что b и c являются оцененными булевской переменной выражениями.

16.1.12 Условный Оператор ? :

Предположите, что b и c являются выражениями, которые не оцениваются булевской переменной.

16.1.13 Булевы Выражения Присвоения

Предположите что выражение a присвоения = b, a &= b, a |= b, или a ^= b является булевской переменной - оцененный.

Отметьте это, если V и V определенно не присваивается перед составным присвоением, таким как a &= b, затем ошибка времени компиляции обязательно произойдет. Вышеизложенные правила включают разобщенное "V" так, чтобы V, как полагали, был определенно присвоен в более поздних точках в коде. Включая разобщенное "V" не влияет на выбор из двух альтернатив относительно того, является ли программа приемлемой или приведет к ошибке времени компиляции, но это влияет, сколько различных точек в коде может быть расценено как ошибочные, и так практически это может улучшить качество сообщения об ошибке.

16.1.14 Другие Выражения Присвоения

Предположите что выражение a присвоения = b, a += b, a -= b, a *= b, a /= b, a %= b, a <<= b, a >>= b, a >>>= b, a &= b, a |= b, или a ^= b не оценивается булевской переменной.

16.1.15 Операторы ++ и --

16.1.16 Другие Выражения

Если выражение не оценивается булевской переменной и не является выражением условного оператора или выражением присвоения, следующие правила применяются:

Для любого непосредственного подвыражения y выражения x, V определенно присваивается, прежде y эквивалентность V определенно присваивается, прежде x или одна из следующих ситуаций истина:

16.2 Определенное Присвоение и Операторы

16.2.1 Пустые Операторы

16.2.2 Блоки

16.2.3 Операторы объявления Локальной переменной

16.2.4 Помеченные операторы

16.2.5 Операторы выражения

16.2.6 if Операторы

16.2.7 switch Операторы

16.2.8 while Операторы

16.2.9 do Операторы

16.2.10 for Операторы

16.2.10.1 Часть инициализации

16.2.10.2 Часть приращения

16.2.11 break, continue, return, и throw Операторы

16.2.12 synchronized Операторы

16.2.13 try Операторы

V определенно присваивается прежде a finally блочная эквивалентность V определенно присваивается перед try оператор.


Содержание | Предыдущий | Следующий | Индекс

Спецификация языка Java (HTML, сгенерированный Блинчиком "сюзет" Pelouch 24 февраля 1998)
Авторское право © Sun Microsystems, Inc 1996 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к doug.kramer@sun.com

free hit counter