Spec-Zone .ru
спецификации, руководства, описания, API
|
ГЛАВА 6
Имена используются, чтобы обратиться к объектам, объявленным в программе Java. Объявленный объект (§6.1) является пакетом, типом класса, интерфейсным типом, элемент (поле или метод) ссылочного типа, параметр (к методу, конструктору, или обработчику исключений), или локальная переменная.
Имена в программах Java или просты, состоя из единственного идентификатора, или квалифицированный, состоя из последовательности идентификаторов, разделенных".
"маркеры (§6.2).
У каждого имени, представленного объявлением, есть контекст (§6.3), который является частью текста программы Java, в пределах которого объявленный объект может быть упомянут простым именем.
У пакетов и ссылочных типов (то есть, типы классов, интерфейсные типы, и типы массива) есть элементы (§6.4). Элемент может быть отнесен в использование полностью определенного имени N.
x, то, где N является простым или полностью определенным именем и x, является идентификатором. Если N называет пакет, то x является элементом того пакета, который является или классом или интерфейсным типом или подпакетом. Если N называет ссылочный тип или переменную ссылочного типа, то x называет элемент того типа, который является или полем или методом.
В определении значения имени (§6.5), Java использует контекст возникновения, чтобы снять неоднозначность среди пакетов, типов, переменных, и методов с тем же самым именем.
Управление доступом (§6.6) может быть определено в классе, интерфейсе, методе, или полевом объявлении, чтобы управлять, когда доступ к элементу предоставляется. Доступ является различным понятием от контекста; доступ определяет часть текста программы Java, в пределах которого объявленный объект может быть упомянут полностью определенным именем, выражение доступа к полю (§15.10), или выражение вызова метода (§15.11), в котором метод не определяется простым именем. Доступ по умолчанию - то, что к элементу можно получить доступ где угодно в пределах пакета, который содержит его объявление; другие возможности public
, protected
, и private
.
Полностью определенные имена (§6.7) и соглашения о присвоении имен (§6.8) также обсуждаются в этой главе.
Имя поля, параметра, или локальной переменной может использоваться в качестве выражения (§15.13.1). Имя метода может появиться в выражении только как часть выражения вызова метода (§15.11). Имя класса или интерфейсного типа может появиться в выражении только как часть выражения создания экземпляра класса (§15.8), выражение создания массива (§15.9), выражение броска (§15.15), или instanceof
выражение (§15.19.2), или как часть полностью определенного имени для поля или метода. Имя пакета может появиться в выражении только как часть полностью определенного имени для класса или соединить интерфейсом с типом.
package
объявление (§7.4)
abstract
метод интерфейса (§9.4)
catch
пункт a try
оператор (§14.18)
Есть две формы имен: простые имена и полностью определенные имена. Простое имя является единственным идентификатором. Полностью определенное имя состоит из имени,".
"маркер, и идентификатор.
В определении значения имени (§6.5), язык Java принимает во внимание контекст, в котором появляется имя. Это различает среди контекстов, где имя должно обозначить (обратитесь к), пакет (§6.5.3), тип (§6.5.4), переменная или значение в выражении (§6.5.5), или метод (§6.5.6).
Не все идентификаторы в программах Java являются частью имени. Идентификаторы также используются в следующих ситуациях:
.
"маркер, чтобы указать на элемент объекта, который является значением выражения или ключевого слова super
это появляется перед".
"маркер
.
"маркер и перед"(
"маркер, чтобы указать на метод, который будет вызван для объекта, который является значением выражения или ключевого слова super
это появляется перед".
"маркер
break
(§14.13) и continue
операторы (§14.14), которые обращаются к меткам оператора class Test { public static void main(String[] args) { Class c = System.out.getClass(); System.out.println(c.toString().length() + args[0].length() + args.length); } }идентификаторы
Test
, main
, и первые возникновения args
и c
не имена; скорее они используются в объявлениях, чтобы определить имена объявленных объектов. Имена String
, Class
, System.out.getClass,
System.out.println
, c.toString
, args
, и args.length
появитесь в примере. Первое возникновение length
не имя, а скорее идентификатор, появляющийся в выражении вызова метода (§15.11). Второе возникновение length
не имя, а скорее идентификатор, появляющийся в выражении вызова метода (§15.11). Идентификаторы, используемые в помеченных операторах и их связанном break
и continue
операторы являются абсолютно отдельными от используемых в объявлениях. Таким образом следующий код допустим:
class TestString {Этот код был взят от версии класса
char[] value;
int offset, count;
int indexOf(TestString str, int fromIndex) { char[] v1 = value, v2 = str.value; int max = offset + (count - str.count); int start = offset + ((fromIndex < 0) ? 0 : fromIndex); i: for (int i = start; i <= max; i++)
{ int n = str.count, j = i, k = str.offset; while (n-- != 0) { if (v1[j++] != v2[k++]) continue i; } return i - offset; } return -1; } }
String
и его метод indexOf
(§20.12.26), где метку первоначально вызвали test
. Изменение метки, чтобы иметь то же самое имя как локальная переменная i
не скрывает метку в пределах объявления i
. Идентификатор max
возможно, также использовался в качестве метки оператора; метка не скрыла бы локальную переменную max
в пределах помеченного оператора. package
объявление, определяется хост-системой (§7.4.3). Весь код Java в рамках стандартного названного пакета java
, так пакет java
может всегда упоминаться кодом Java.
class Test { int i = j; // compile-time error: incorrect forward reference int j = 1; }
class Test { Test() { k = 2; } int j = 1; int i = j; int k; }
Test
обращается к полю k
это объявляется тремя строками позже. for
оператор (§14.12) включает все следующее: for
оператор
for
оператор
catch
пункт a try
оператор (§14.18) является всем блоком, связанным с catch
.
package points;
class Point { int x, y; PointList list; Point next; } class PointList { Point first; }использование
PointList
в классе Point
корректно, потому что контекст типа класса называет PointList
включает оба класса Point
и класс PointList
, так же как любые другие описания типа в других единицах компиляции пакета points
.
class Test { static int x = 1; public static void main(String[] args) { int x = 0; System.out.print("x=" + x); System.out.println(", Test.x=" + Test.x); } }производит вывод:
x=0, Test.x=1Этот пример объявляет:
Test
static
) переменная x
это - элемент класса Test
main
это - элемент класса Test
args
из main
метод
x
из main
метод x
обычно было бы доступно всюду по всему телу метода main
. В этом примере, однако, переменной класса x
скрывается в пределах тела метода main
объявлением локальной переменной x
.
Локальная переменная имеет как ее остальная часть контекста блока, в котором она объявляется (§14.3.2); в этом случае это - остальная часть тела main
метод, а именно, его инициализатор"0
"и вызовы print
и println
.
x
"в вызове print
обращается к (обозначает) значение локальной переменной x
.
println
использует полностью определенное имя (§6.6) Test.x
, который использует имя типа класса Test
получить доступ к переменной класса x
, потому что объявление Test.x
скрывается в этой точке и не может быть упомянут ее простым именем.
class Point { int x, y; } class Test { static Point Point(int x, int y) { Point p = new Point(); p.x = x; p.y = y; return p; }Это компилирует без ошибки и выполняется, чтобы произвести вывод:
public static void main(String[] args) { int Point; Point[] pa = new Point[2]; for (Point = 0; Point < 2; Point++) { pa[Point] = new Point(); pa[Point].x = Point; pa[Point].y = Point; } System.out.println(pa[0].x + "," + pa[0].y); System.out.println(pa[1].x + "," + pa[1].y); Point p = Point(3, 4); System.out.println(p.x + "," + p.y); }
}
0,0 1,1В пределах тела
3,4
main
, поиски Point
найдите различные объявления в зависимости от контекста использования: new
Point[2]
", два возникновения выражения создания экземпляра класса"new
Point()
", и в начале трех различных операторов объявления локальной переменной, Point
TypeName (§6.5.4) и обозначает тип класса Point
в каждом случае.
Point(3,
4)
"возникновение Point
MethodName (§6.5.6) и обозначает класс (static
) метод Point
.
Point
. import java.util.*;
class Vector { int val[] = { 1 , 2 }; }компиляции и печатные издания:
class Test { public static void main(String[] args) { Vector v = new Vector(); System.out.println(v.val[0]); } }
1использование класса
Vector
объявленный здесь в предпочтении к классу java.util.Vector
это могло бы быть импортировано по требованию. Этот раздел обеспечивает краткий обзор элементов пакетов и ссылочных типов здесь как фон для обсуждения полностью определенных имен и определения значения имен. Для полного описания членства см. §7.1, §8.2, §9.2, и §10.7.
Вообще, подпакеты пакета определяются хост-системой (§7.2). Однако, стандартный пакет java
всегда включает подпакеты lang
, util
, io
, и net
и может включать другие подпакеты. Ни у каких двух отличных элементов того же самого пакета не может быть того же самого простого имени (§7.1), но у элементов различных пакетов может быть то же самое простое имя. Например, возможно объявить пакет:
package vector; public class Vector { Object[] vec; }это имеет как элемент a
public
класс называют Vector
, даже при том, что стандартный пакет java.util
также объявляет названный класс Vector
. Эти два типов классов отличаются, отражаются фактом, что у них есть различные полностью определенные имена (§6.7). Полностью определенное имя этого примера Vector
vector.Vector
, тогда как java.util.Vector
полностью определенное имя стандарта Vector
класс. Поскольку пакет vector
содержит названный класс Vector
, этому нельзя было также назвать подпакет Vector
. Object
не имеет никакого прямого суперкласса),
Нет никакого ограничения против поля и метода типа класса, имеющего то же самое простое имя.
У класса может быть два или больше поля с тем же самым простым именем, если они объявлены в различных интерфейсах и наследованы. Попытка обратиться к любому из полей ее простым именем приводит к ошибке времени компиляции (§6.5.6.2, §8.2).
interface Colors { int WHITE = 0, BLACK = 1; } interface Separates { int CYAN = 0, MAGENTA = 1, YELLOW = 2, BLACK = 3; } class Test implements Colors, Separates { public static void main(String[] args) { System.out.println(BLACK); // compile-time error: ambiguous } }имя
BLACK
в методе main
неоднозначно, потому что класс Test
имеет два названные элемента BLACK
, один наследованный от Colors
и один от Separates
. У типа класса может быть два или больше метода с тем же самым простым именем, если у методов есть различные подписи (§8.4.2), то есть, если у них есть различные числа параметров, или различный параметр вводит по крайней мере одну позицию параметра. Такое имя элемента метода, как говорят, перегружается.
Тип класса может содержать объявление для метода с тем же самым именем и той же самой подписью как метод, который был бы иначе наследован от суперкласса или суперинтерфейса. В этом случае метод суперкласса или суперинтерфейса не наследован. Если метод, не наследованный, abstract
, тогда новое объявление, как говорят, реализует это; если метод, не наследованный, не abstract
, тогда новое объявление, как говорят, переопределяет это.
class Point { float x, y; void move(int dx, int dy) { x += dx; y += dy; } void move(float dx, float dy) { x += dx; y += dy; } public String toString() { return "("+x+","+y+")"; } }класс
Point
имеет два элемента, которые являются методами с тем же самым именем, move
. Перегруженный move
метод класса Point
выбранный для любого определенного вызова метода определяется во время компиляции перегружающейся процедурой разрешения, данной в §15.11. В этом примере, элементах класса Point
float
переменные экземпляра x
и y
объявленный в Point
, эти объявленные два move
методы, объявленный toString
метод, и элементы это Point
наследовался от его неявного прямого суперкласса Object
(§4.3.2), такой как метод hashCode
(§20.1.4). Отметьте это Point
не наследовался toString
метод (§20.1.2) класса Object
потому что тот метод переопределяется объявлением toString
метод в классе Point
.
interface Colors { int WHITE = 0, BLACK = 1; } interface Separates { int CYAN = 0, MAGENTA = 1, YELLOW = 2, BLACK = 3; } interface ColorsAndSeparates extends Colors, Separates {элементы интерфейса
int DEFAULT = BLACK; // compile-time error: ambiguous
}
ColorsAndSeparates
включайте те элементы, наследованные от Colors
и наследованные от Separates
, а именно, WHITE
, BLACK
(сначала два), CYAN
, MAGENTA
, YELLOW
, и BLACK
(второй из два). Имя элемента BLACK
неоднозначно в интерфейсе ColorsAndSeparates
. Object
(§4.3.2, §20.1)
length
, который является константой (final
) поле каждого массива; его тип int
и это содержит число компонентов массива class Test { public static void main(String[] args) { int[] ia = new int[3]; int[] ib = new int[6]; System.out.println(ia.getClass() == ib.getClass()); System.out.println("ia has length=" + ia.length); } }производит вывод:
true ia has length=3Этот пример использует метод
getClass
унаследованный от класса Object
и поле length
. Результат сравнения Class
объекты во втором println
демонстрирует, что все массивы, компоненты которых имеют тип int
экземпляры того же самого типа массива, который является int[]
. PackageName:Использование Java контекста помогает минимизировать конфликты имен между объектами различных видов. Такие конфликты будут редки, если соглашения о присвоении имен, описанные в §6.8, будут сопровождаться. Однако, конфликты могут возникнуть неумышленно как типы, разработанные различными программистами, или различные организации развиваются. Например, у типов, методов, и полей может быть то же самое имя. Java никогда не испытывает затруднения, различая метод и поле с тем же самым именем, так как контекст использования всегда говорит, предназначаются ли метод или поле.
Identifier
PackageName.
Identifier TypeName:
Identifier
PackageName.
Identifier ExpressionName:
Identifier
AmbiguousName.
Identifier MethodName:
Identifier
AmbiguousName.
Identifier AmbiguousName:
Identifier
AmbiguousName.
Identifier
.
"в квалифицированном PackageName
.
"в квалифицированном TypeName
extends
пункт в объявлении класса (§8.1.3)
implements
пункт в объявлении класса (§8.1.4)
extends
пункт в интерфейсном объявлении (§9.1.3)
catch
пункт a try
оператор (§14.18)
instanceof
оператор отношения (§15.19.2)
(
"в выражении вызова метода (§15.11)
.
"в квалифицированном ExpressionName
.
"в квалифицированном MethodName
.
"в квалифицированном AmbiguousName
.
", и Идентификатор, тогда имя налево от".
"сначала повторно классифицируется, поскольку это - самостоятельно AmbiguousName. Есть тогда выбор: .
"повторно классифицируется как PackageName, тогда есть дальнейший выбор: .
"и тот пакет содержит объявление типа, имя которого является тем же самым как Идентификатором, тогда этот AmbiguousName повторно классифицируется как TypeName.
.
"повторно классифицируется как TypeName, тогда этот AmbiguousName повторно классифицируется как ExpressionName.
.
"повторно классифицируется как ExpressionName, тогда этот AmbiguousName повторно классифицируется как ExpressionName.
и затем рассмотрите этот пример кода в другом пакете:
package ORG.rpgpoet;
import java.util.Random;
interface Music { Random[] wizards = new Random[4]; }
package bazola;
class Gabriel { static int n = ORG.rpgpoet.Music.wizards.length; }Прежде всего, имя
ORG.rpgpoet.Music.wizards.length
классифицируется как ExpressionName, потому что он функционирует как PostfixExpression. Поэтому, каждое из имен: ORG.rpgpoet.Music.wizards ORG.rpgpoet.Music ORG.rpgpoet ORGпервоначально классифицируется как AmbiguousName. Они тогда повторно классифицируются:
ORG
в любой другой единице компиляции пакета bazola
, тогда простое имя ORG
повторно классифицируется как PackageName.
rpgpoet
в любой единице компиляции пакета ORG
(и мы знаем, что нет такого класса или интерфейса потому что пакет ORG
назвали подпакет rpgpoet
), полностью определенное имя ORG.rpgpoet
повторно классифицируется как PackageName.
ORG.rpgpoet
имеет интерфейсный названный тип Music
, полностью определенное имя ORG.rpgpoet.Music
повторно классифицируется как TypeName.
ORG.rpgpoet.Music
TypeName, полностью определенное имя ORG.rpgpoet.Music.wizards
повторно классифицируется как ExpressionName. .
Идентификатор, тогда Q должен также быть именем пакета. Имя Q пакета.
Идентификатор называет пакет, который является элементом под названием Идентификатор в пределах пакета, названного Q. Если Q не называет доступный пакет, или Идентификатор не называет доступный подпакет того пакета, то ошибка времени компиляции происходит. .
Идентификатор, тогда Q должен быть именем пакета. Имя типа Q.
Идентификатор называет тип, который является элементом под названием Идентификатор в пределах пакета, названного Q. Если Q не называет доступный пакет, или Идентификатор не называет тип в пределах того пакета, или тип под названием Идентификатор в пределах того пакета не доступен (§6.6), то ошибка времени компиляции происходит.
package wnj.test;
class Test { public static void main(String[] args) { java.util.Date date = new java.util.Date(System.currentTimeMillis()); System.out.println(date.toLocaleString()); } }произведенный следующий вывод в первый раз это было выполнено:
Sun Jan 21 22:56:29 1996В этом примере:
wnj.test
должен назвать пакет на хост-системе. Это разрешается первым поиском пакета wnj
, использование процедуры, описанной в §6.5.3.1, и затем удостоверяясь, что подпакет test
из этого пакета доступно.
java.util.Date
(§21.3) должен обозначить тип, таким образом, мы сначала используем процедуру рекурсивно, чтобы определить если java.util
доступный пакет, который это, и затем надейтесь видеть если тип Date
доступно в этом пакете. final
(§8.3.1.2), тогда имя выражения обозначает значение поля. Тип имени выражения является объявленным типом поля. Если Идентификатор появляется в контексте, который требует переменной и не значения, то ошибка времени компиляции происходит.
static
метод (§8.4.3.2), статический инициализатор (§8.5), или инициализатор для a static
переменная (§8.3.1.1, §12.4.2), затем ошибка времени компиляции происходит. class Test {имена, используемые в качестве левых сторон в присвоениях на
static int v;
static final int f = 3;
public static void main(String[] args) { int i; i = 1; v = 2; f = 33; // compile-time error System.out.println(i + " " + v + " " + f); }
}
i
, v
, и f
обозначьте локальную переменную i
, поле v
, и значение f
(не переменная f
, потому что f
a final
переменная). Пример поэтому производит ошибку во время компиляции, потому что у последнего присвоения нет переменной как ее левой стороны. Если ошибочное присвоение удаляется, измененный код может быть скомпилирован, и это произведет вывод: 1 2 3
.
Идентификатор, тогда Q был уже классифицирован как имя пакета, имя типа, или имя выражения: static
), затем ошибка времени компиляции происходит.
final
, тогда Q.
Идентификатор обозначает значение переменной класса. Тип выражения Q.
Идентификатор является объявленным типом переменной класса. Если Q.
Идентификатор появляется в контексте, который требует переменной и не значения, затем ошибка времени компиляции происходит.
.
Идентификатор обозначает переменную класса. Тип выражения Q.
Идентификатор является объявленным типом переменной класса. .
Идентификатор обозначает значение поля. Тип выражения Q.
Идентификатор является объявленным типом поля. Если Q.
Идентификатор появляется в контексте, который требует переменной и не значения, затем ошибка времени компиляции происходит. final
поле типа класса (который может быть или переменной класса или переменной экземпляра),
final
поле length
из типа массива .
Идентификатор обозначает значение поля. Тип выражения Q.
Идентификатор является объявленным типом поля. Если Q.
Идентификатор появляется в контексте, который требует переменной и не значения, затем ошибка времени компиляции происходит.
.
Идентификатор обозначает переменную, поле Id класса T, который может быть или переменной класса или переменной экземпляра. Тип выражения Q.
Идентификатор является объявленным типом поля class Point { int x, y; static int nPoints; } class Test { public static void main(String[] args) { int i = 0; i.x++; // compile-time error Point p = new Point(); p.nPoints(); // compile-time error } }встречается с двумя ошибками времени компиляции, потому что
int
переменная i
не имеет никаких элементов, и потому что nPoints
не метод класса Point
. .
Идентификатор, тогда Q был уже классифицирован как имя пакета, имя типа, или имя выражения. Если Q является именем пакета, то ошибка времени компиляции происходит. Иначе, Айдахо является именем метода, которое будет использоваться для вызова метода. Если Q является именем типа, то Идентификатор должен назвать по крайней мере один static
метод типа Q. Если Q является именем выражения, то T, которым позволяют, являются типом выражения Q; Идентификатор должен назвать по крайней мере один метод типа T. См. §15.11 для дальнейшего обсуждения интерпретации квалифицированных имен методов в выражениях вызова метода. .
"маркер кажется, предшествовавшим некоторой индикацией относительно пакета, введите, или выражение, имеющее тип и сопровождаемый Идентификатором, который называет элемент пакета или типа. Они все вместе известны как конструкции для квалифицированного доступа. Java обеспечивает механизмы для управления доступом, чтобы предотвратить пользователей пакета или класса от в зависимости от ненужных деталей реализации того пакета или класса. Управление доступом применяется к квалифицированному доступу и к вызову конструкторов по выражениям создания экземпляра класса (§15.8), явные вызовы конструктора (§8.6.5), и метод newInstance
из класса Class
(§20.3.6).
Если доступ разрешается, то объект, к которому получают доступ, как говорят, доступен.
public
, тогда к этому может получить доступ любой код Java, который может получить доступ к пакету, в котором это объявляется. Если класс или интерфейсный тип не объявляются public
, тогда к этому можно получить доступ только изнутри пакета, в котором это объявляется.
public
, тогда доступ разрешается. Все элементы интерфейсов неявно public
.
protected
, тогда доступ разрешается только, когда одно из следующего является истиной: protected
элемент объявляется.
protected
элемент объявляется, и доступ корректен как описано в §6.6.2. private
, тогда доступ разрешается только, когда он происходит изнутри класса, в котором он объявляется.
protected
Доступprotected
к элементу или конструктору объекта можно получить доступ снаружи пакета, в котором он объявляется только кодом, который ответственен за реализацию того объекта. Позвольте C быть классом в который a protected
элемент или конструктор объявляются и позволяются S быть подклассом C в чей объявлении использование protected
элемент или конструктор происходят. Затем: protected
элемент (поле или метод), позвольте Идентификатору быть своим именем. Рассмотрите тогда средства квалифицированного доступа: super.
Идентификатор, тогда доступ разрешается.
.
Идентификатор, где Q является TypeName, тогда доступ, разрешается, если и только если Q является S или подклассом S.
.
Идентификатор, где Q является ExpressionName, тогда доступ, разрешается, если и только если тип выражения Q является S или подклассом S.
.
Идентификатор, где E является Основным выражением, или по выражению E вызова метода.
Идентификатор(
. . .)
, где E является Основным выражением, тогда доступ разрешается, если и только если тип E является S или подклассом S. protected
конструктор: super(
. . .)
, тогда доступ разрешается.
new
T(
. . .)
, тогда доступ не разрешается. (A protected
к конструктору может получить доступ выражение создания экземпляра класса только изнутри пакета, в котором оно определяется.)
newInstance
из класса Class
(§20.3.6), тогда доступ не разрешается. и:
package points;
class PointVec { Point[] vec; }
package points;
public class Point { protected int x, y; public void move(int dx, int dy) { x += dx; y += dy; } public int getX() { return x; } public int getY() { return y; } }которые объявляют два типов классов в пакете
points
: PointVec
не public
и не часть public
интерфейс пакета points
, а скорее может использоваться только другими классами в пакете.
Point
объявляется public
и доступно другим пакетам. Это - часть public
интерфейс пакета points
.
move
, getX
, и getY
из класса Point
объявляются public
и так доступны любому коду Java, который использует объект типа Point
.
x
и y
объявляются protected
и доступны вне пакета points
только в подклассах класса Point,
и только когда они - поля объектов, которые реализуются кодом, который получает доступ к ним. protected
модификатор доступа ограничивает доступ. public
и не -public
Классыpublic
модификатор, доступ к объявлению класса ограничивается пакетом, в котором это объявляется (§6.6). В примере:
package points;
public class Point { public int x, y; public void move(int dx, int dy) { x += dx; y += dy; } }два класса объявляются в единице компиляции. Класс
class PointList { Point next, prev; }
Point
доступно вне пакета points
, в то время как класс PointList
доступно для доступа только в пределах пакета. Таким образом единица компиляции в другом пакете может получить доступ points.Point
, любой при использовании его полностью определенного имени:
package pointsUser;
class Test { public static void main(String[] args) { points.Point p = new points.Point(); System.out.println(p.x + " " + p.y); } }или при использовании объявления единственного импорта типа (§7.5.1), который упоминает полностью qualfied имя, так, чтобы простое имя могло использоваться после того:
package pointsUser;
import points.Point;
class Test { public static void main(String[] args) { Point p = new Point(); System.out.println(p.x + " " + p.y); } }Однако, эта единица компиляции не может использовать или импортировать
points.PointList
, который не объявляется public
и поэтому недоступный внешний пакет points
. public
, protected
, или private
определяются, элемент класса или конструктор доступны всюду по пакету, который содержит объявление класса, в котором объявляется элемент класса, но элемент класса или конструктор не доступны в любом другом пакете. Если a public
у класса есть метод или конструктор с доступом по умолчанию, тогда этот метод или конструктор не доступны для или наследованный подклассом, объявленным вне этого пакета.
package points;
public class Point { public int x, y; void move(int dx, int dy) { x += dx; y += dy; } public void moveAlso(int dx, int dy) { move(dx, dy); } }тогда подкласс в другом пакете может объявить несвязанное
move
метод, с той же самой подписью (§8.4.2) и тип возврата. Поскольку оригинал move
метод не доступен от пакета morepoints
, super
возможно, не используется:
package morepoints;
public class PlusPoint extends points.Point { public void move(int dx, int dy) { super.move(dx, dy); // compile-time error moveAlso(dx, dy); } }Поскольку перемещение
Point
не переопределяется move
в PlusPoint
, метод moveAlso
в Point
никогда не призывает перемещение метода PlusPoint
. Таким образом, если Вы удаляете super.move
вызовите от PlusPoint
и выполните тестовую программу:
import points.Point; import morepoints.PlusPoint; class Test { public static void main(String[] args) { PlusPoint pp = new PlusPoint(); pp.move(1, 1); }это обычно завершается. Если перемещение
}
Point
были переопределены move
в PlusPoint
, тогда эта программа рекурсивно вызвала бы бесконечно, до a StackoverflowError
произошедший. public
Поля, Методы, и Конструкторыpublic
элемент класса или конструктор доступны всюду по пакету, откуда это объявляется и любого другого пакета, у которого есть доступ к пакету, в котором это объявляется (§7.4.4). Например, в единице компиляции:
package points;
public class Point {
int x, y;
public void move(int dx, int dy) { x += dx; y += dy; moves++; }
public static int moves = 0;
}
public
класс Point
имеет как public
элементы move
метод и moves
поле. Они public
элементы доступны для любого другого пакета, у которого есть доступ к пакету points
. Поля x
и y
не public
и поэтому доступны только изнутри пакета points
. protected
Поля, Методы, и Конструкторыpoint
пакет объявляет:
package points;
public class Point {и
protected int x, y;
void warp(threePoint.Point3d a) { if (a.z > 0) // compile-time error: cannot access a.z a.delta(this); }
}
threePoint
пакет объявляет:
package threePoint;
import points.Point;
public class Point3d extends Point {который определяет класс
protected int z;
public void delta(Point p) { p.x += this.x; // compile-time error: cannot access p.x p.y += this.y; // compile-time error: cannot access p.y }
public void delta3d(Point3d q) { q.x += this.x; q.y += this.y; q.z += this.z; }
}
Point3d
. Ошибка времени компиляции происходит в методе delta
здесь: это не может получить доступ к защищенным элементам x
и y
из его параметра p
, потому что, в то время как Point3d
(то класс, в который ссылки на поля x
и y
происходите), подкласс Point
(то класс, в который x
и y
объявляются), это не включается в реализацию a Point
(тип параметра p
). Метод delta3d
может получить доступ к защищенным элементам его параметра q
, потому что класс Point3d
подкласс Point
и включается в реализацию a Point3d
. Метод delta
мог попытаться бросить (§5.4, §15.15) его параметр, чтобы быть a Point3d
, но этот бросок перестал бы работать, вызывая исключение, если класс p
во время выполнения не были Point3d
.
Ошибка времени компиляции также происходит в деформации метода: это не может получить доступ к защищенному элементу z
из его параметра a
, потому что, в то время как класс Point
(то класс, в который ссылка на поле z
происходит), включается в реализацию a Point
(тип параметра a), это не подкласс Point
(то класс, в который z
объявляется).
private
Поля, Методы, и КонструкторыA
private
элемент класса или конструктор доступны только в пределах тела класса, в котором элемент объявляется и не наследован подклассами. В примере: class Point {
Point() { setMasterID(); }
int x, y; private int ID; private static int masterID = 0;
private void setMasterID() { ID = masterID++; }
}
private
элементы ID,
м.asterID
, и setMasterID
может использоваться только в пределах тела класса Point
. К ним не могут получить доступ полностью определенные имена, выражения доступа к полю, или выражения вызова метода вне тела объявления Point
. См. §8.6.8 для примера, который использует a private
конструктор.
boolean
, char
, byte
, short
, int
, long
, float
, или double
.
.
", сопровождаемый простым (элемент) имя подпакета.
.
", сопровождаемый простым именем класса или интерфейса.
[]
". long
"long
".
java.lang
"java.lang
"потому что это - подпакет lang
из пакета java
.
Object
, который определяется в пакете java.lang
,"java.lang.Object
".
Enumeration
, который определяется в пакете java.util
,"java.util.Enumeration
".
double
double[]
".
String
java.lang.String[][][][]
". package points;
class Point { int x, y; } class PointVec { Point[] vec; }полностью определенное имя типа
Point
"points.Point
"; полностью определенное имя типа PointVec
"points.PointVec
"; и полностью определенное имя типа поля vec
из класса PointVec
"points.Point[]
". Мы рекомендуем эти соглашения для использования во всех программах Java. Однако, эти соглашения не должны сопровождаться по-рабски если долго сохранено стандартное использование, диктует иначе. Так, например, sin
и cos
методы класса java.lang.Math
имейте математически стандартные имена, даже при том, что эти имена методов презирают соглашение Java, потому что они коротки и не являются глаголами.
COM
, EDU
, GOV
, MIL
, NET
, ORG
, или двухбуквенный код страны ISO такой как UK
или JP
. Вот примеры гипотетических уникальных имен, которые могли бы быть сформированы в соответствии с этим соглашением: COM.JavaSoft.jag.Oak ORG.NPR.pledge.driver UK.ac.city.rugby.gameУ имен пакетов, предназначенных только для локального использования, должен быть первый идентификатор, который начинается со строчной буквы, но что первый идентификатор определенно не должен быть идентификатором
java
; имена пакета, которые запускаются с идентификатора java
резервируются к JavaSoft для того, чтобы назвать стандартные пакеты Java.Когда имена пакета происходят в выражениях:
import
объявления (§7.5) могут обычно использоваться, чтобы сделать доступным имена типов объявленный в том пакете.
Аналогично, имена интерфейсных типов должны быть короткими и дескриптивными, не чрезмерно долго, в смешанном случае с первой буквой каждого использованного для своей выгоды слова. Имя может быть дескриптивным существительным или именной группой, которая является соответствующей, когда интерфейс используется, как будто это был абстрактный суперкласс, такой как интерфейсыClassLoader
SecurityManager
Thread
Dictionary
BufferedInputStream
java.io.DataInput
и java.io.DataOutput
; или это может быть прилагательное, описывающее поведение, что касается интерфейсов java.lang.Runnable
и java.lang.Cloneable
.Сокрытие включения класса и интерфейсных имен типов редко. Имена полей, параметров, и локальных переменных обычно не скрывают имена типов, потому что они традиционно начинают со строчной буквы, тогда как имена типов традиционно начинаются с прописной буквы.
get
и set
атрибут, который мог бы считаться переменной V, нужно назвать get
V и set
V. Примером являются методы getPriority
(§20.20.22) и setPriority
(§20.20.23) класса java.lang.Thread
.
length
, как в классе java.lang.String
(§20.12.11).
boolean
условие V об объекте нужно назвать is
V. Примером является метод isInterrupted
из класса java.lang.Thread
(§20.20.32).
to
F. Примерами является метод toString
из класса java.lang.Object
(§20.1.2) и методы toLocaleString
(§21.3.27) и toGMTString
(§21.3.28) класса java.util.Date
. Имена методов не могут скрыться или быть скрыты другими именами (§6.5.6).
final
должен быть в смешанном случае с нижним регистром, сначала обозначают буквами и первые буквы последующих использованных для своей выгоды слов. Отметьте, что у хорошо разработанных классов Java есть очень немногие public
или protected
поля, за исключением полей, которые являются константами (final
static
поля) (§6.8.5). У полей должны быть имена, которые являются существительными, именными группами, или сокращениями для существительных. Примерами этого соглашения являются поля buf
, pos
, и count
из класса java.io.ByteArrayInputStream
(§22.6) и поле bytesTransferred
из класса java.io.InterruptedIOException
(§22.30.1).
Сокрытие включения имен полей редко.
import
объявление (§7.5) может обычно использоваться, чтобы сделать доступным имена типов объявленный в том пакете.
final
переменные типов классов могут традиционно быть, последовательность одного или более слов, акронимов, или сокращений, всего верхнего регистра, с компонентами, разделенными подчеркиванием"_
"символы. Постоянные имена должны быть дескриптивными и весьма обязательно сокращенными. Традиционно они могут быть любой соответствующей частью речи. Примеры имен для констант включают MIN_VALUE
, MAX_VALUE
, MIN_RADIX
, и MAX_RADIX
из класса java.lang.Character
. Группа констант, которые представляют альтернативные значения набора, или, менее часто, маскируя биты в целочисленном значении, иногда полезно определяется с общим акронимом как префикс имени, как в:
interface ProcessStates { int PS_RUNNING = 0; int PS_SUSPENDED = 1; }Сокрытие включения постоянных имен редко:
cp
для переменной, содержащей ссылку на a ColoredPoint
buf
содержание указателя на a buffer
из некоторого вида
b
для a byte
c
для a char
d
для a double
e
для Exception
f
для a float
i
, j
, и k
для целых чисел
l
для a long
o
для Object
s
для a String
v
для произвольного значения некоторого типа
Содержание | Предыдущий | Следующий | Индекс
Спецификация языка Java (HTML, сгенерированный Блинчиком "сюзет" Pelouch 24 февраля 1998)
Авторское право © Sun Microsystems, Inc 1996 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к doug.kramer@sun.com