1 |
tdb |
1.1 |
Coding Standards |
2 |
|
|
================ |
3 |
|
|
|
4 |
|
|
tdb1, 28/11/20000 |
5 |
|
|
|
6 |
|
|
|
7 |
|
|
Document description |
8 |
|
|
==================== |
9 |
|
|
|
10 |
|
|
The purpose of this document is to provide a defined |
11 |
|
|
standard to which all code will conform. This will ensure |
12 |
|
|
consistency across all files, and allow all members of the |
13 |
|
|
team to easily follow the different pieces written by other |
14 |
|
|
members. |
15 |
|
|
|
16 |
|
|
|
17 |
|
|
Contents |
18 |
|
|
======== |
19 |
|
|
|
20 |
|
|
- Foreword |
21 |
|
|
|
22 |
|
|
- Structure & Layout |
23 |
|
|
|
24 |
|
|
- Identifiers |
25 |
|
|
- Final Variables |
26 |
|
|
- Indentation and Layout |
27 |
|
|
- Bracketing |
28 |
|
|
- Exceptions |
29 |
|
|
- Access Control |
30 |
|
|
- Imports |
31 |
|
|
- Overall Class Layout |
32 |
|
|
|
33 |
|
|
- Naming Conventions |
34 |
|
|
|
35 |
|
|
- Commenting & Documentation |
36 |
|
|
|
37 |
|
|
- Class and Interfaces |
38 |
|
|
- Methods |
39 |
|
|
- Attributes and Variables |
40 |
|
|
- General Commenting |
41 |
|
|
|
42 |
|
|
- General Recommendations |
43 |
|
|
|
44 |
|
|
- Threading |
45 |
|
|
- Class Design |
46 |
|
|
- Platform |
47 |
|
|
|
48 |
|
|
|
49 |
|
|
Foreword |
50 |
|
|
======== |
51 |
|
|
|
52 |
|
|
In constructing this document I have heavily used content |
53 |
|
|
found in the following documents. I have tried to use these |
54 |
|
|
documents to give our Coding Standard a solid foundation, |
55 |
|
|
without doing a lot of unnecessary work that has already |
56 |
|
|
been done by these authors. |
57 |
|
|
|
58 |
|
|
The majority of this document is taken from the book by |
59 |
|
|
David Barnes, with the other two just being used for small |
60 |
|
|
parts which David hasn't covered in as much detail. |
61 |
|
|
|
62 |
|
|
Java Stylistic Conventions, by David Barnes |
63 |
tdb |
1.2 |
http://www.cs.kent.ac.uk/people/staff/djb/Book/style.html |
64 |
tdb |
1.1 |
Draft Java Coding Standard, by Doug Lea |
65 |
|
|
http://g.oswego.edu/dl/html/javaCodingStd.html |
66 |
|
|
Netscape's Java Coding Standards Guide |
67 |
|
|
http://developer.netscape.com/docs ... |
68 |
|
|
... /technote/java/codestyle.html |
69 |
|
|
|
70 |
|
|
|
71 |
|
|
Structure & Layout |
72 |
|
|
================== |
73 |
|
|
|
74 |
|
|
Identifiers |
75 |
|
|
----------- |
76 |
|
|
|
77 |
|
|
Identifiers can come down to simple imagination, and there |
78 |
|
|
isn't a right or wrong way of doing it. The only restriction |
79 |
|
|
is that they should be descriptive and of a reasonable |
80 |
|
|
length. A variable name should have a single use and a name |
81 |
|
|
fitting to this use, rather than using a single |
82 |
|
|
non-descriptive name for multiple purposes. |
83 |
|
|
|
84 |
|
|
A common convention is that names of methods, attributes, |
85 |
|
|
and variables should begin with an initial lower-case letter |
86 |
|
|
and have a single upper-case letter at the start of each new |
87 |
|
|
word within the name. Class names should begin with an |
88 |
|
|
uppercase letter and follow the same rule for the start of |
89 |
|
|
each new word. Examples of these could be: |
90 |
|
|
|
91 |
|
|
myVariable |
92 |
|
|
aClassAttribute |
93 |
|
|
|
94 |
|
|
aUsefulMethod() |
95 |
|
|
|
96 |
|
|
CleverClassName |
97 |
|
|
|
98 |
|
|
Accessor and Mutators should have names based on the |
99 |
|
|
attribute to which they provide access. They should begin |
100 |
|
|
with the prefix get or set followed by the name of the |
101 |
|
|
attribute beginning with a capital letter. For example the |
102 |
|
|
variable item would have the following accessor and mutator: |
103 |
|
|
|
104 |
|
|
getItem() |
105 |
|
|
setItem() |
106 |
|
|
|
107 |
|
|
Variable names with a single character, such as x, should be |
108 |
|
|
avoided as they convey little about their use. The only |
109 |
|
|
exception to this rule is when it is used as a loop-control |
110 |
|
|
variable in a for-loop. In this instance the variable serves |
111 |
|
|
only as a counter, and this is obvious from it's use. |
112 |
|
|
|
113 |
|
|
Method variables are those used within a method and should |
114 |
|
|
be used in preference to an attribute if their use is to be |
115 |
|
|
short. They should be defined as close to their use as |
116 |
|
|
possible to make code easier to follow. Use should be made |
117 |
|
|
of the fact that variables defined within nested blocks are |
118 |
|
|
only visible within the block of code, and thus is only |
119 |
|
|
visible to it's related code. |
120 |
|
|
|
121 |
|
|
Final Variables |
122 |
|
|
--------------- |
123 |
|
|
|
124 |
|
|
It is important to avoid the use of magic numbers within the |
125 |
|
|
code. The main reason for this is that it can be hard to |
126 |
|
|
identify which numbers should be changed if the use of the |
127 |
|
|
program needs to be altered. Instead a final variable should |
128 |
|
|
be defined in the program: |
129 |
|
|
|
130 |
|
|
private final int ST = 2; |
131 |
|
|
private final int E = 3; |
132 |
|
|
private final int S = 1; |
133 |
|
|
|
134 |
|
|
The only time when magic numbers are acceptable is when they |
135 |
|
|
are used as a variable initialiser or as a simple step. |
136 |
|
|
Sometimes final variables are needed by more than one class, |
137 |
|
|
in which case they should be defined as public static final |
138 |
|
|
instead. These types of variables with public visibility |
139 |
|
|
should be placed at the start of the class definition |
140 |
|
|
|
141 |
|
|
Final variables should also have all upper-case names, thus |
142 |
|
|
making them clearly identifiable over class attributes. The |
143 |
|
|
use of the final word will also dictate that they cannot be |
144 |
|
|
changed, so accessor's and mutator's are not necessary. |
145 |
|
|
|
146 |
|
|
Indentation and Layout |
147 |
|
|
---------------------- |
148 |
|
|
|
149 |
|
|
Lines should be kept to a sensible length to make the code |
150 |
|
|
easier to read and print. Lines should be broken at a |
151 |
|
|
sensible point and indented further than the current level |
152 |
|
|
of identation. If space permits they should be lined up as |
153 |
|
|
appropriate with the previous line: |
154 |
|
|
|
155 |
|
|
private static final byte[] packet = { Datatypes.FLAG, |
156 |
|
|
Datatypes.TERM, |
157 |
|
|
Datatypes.FLAG, |
158 |
|
|
}; |
159 |
|
|
|
160 |
|
|
Indentation should be four spaces for each level, and single |
161 |
|
|
blank lines should be used to separate methods and to |
162 |
|
|
emphasize blocks of code, as in this example: |
163 |
|
|
|
164 |
|
|
class MyExample { |
165 |
|
|
|
166 |
|
|
public int returnValue(int x){ |
167 |
|
|
return x; |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
} |
171 |
|
|
|
172 |
|
|
Methods should be defined first in a class, preferably in |
173 |
|
|
order of visibility - public methods first, private ones |
174 |
|
|
after. Attributes should be defined after methods for the |
175 |
|
|
class, exception for public final variables which should be |
176 |
|
|
defined first. This will be discussed further in Overall |
177 |
|
|
Class Layout later on in this document. |
178 |
|
|
|
179 |
|
|
Bracketing |
180 |
|
|
---------- |
181 |
|
|
|
182 |
|
|
Brackets are very common in Java code and can be used |
183 |
|
|
sensibly to clearly show the blocks of code they |
184 |
|
|
encapsulate. An opening curly bracket that follows a class |
185 |
|
|
header should be indented by a single space, but those used |
186 |
|
|
after a method header should not. Closing curly brackets |
187 |
|
|
should be placed on the line after the last line of the code |
188 |
|
|
they enclose, at the same level of indentation as the start |
189 |
|
|
of the header on which the block begins: |
190 |
|
|
|
191 |
|
|
class MyExample { |
192 |
|
|
public void method(){ |
193 |
|
|
. . . |
194 |
|
|
} |
195 |
|
|
} |
196 |
|
|
|
197 |
|
|
Curly brackets should always be used for if-, while- and |
198 |
|
|
for-, even when not strictly needed - such as when the body |
199 |
|
|
only contains a single statement. This is the correct way to |
200 |
|
|
do it: |
201 |
|
|
|
202 |
|
|
if(x > largest){ |
203 |
|
|
largest = x; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
|
Sometimes statements within normal brackets need to be |
207 |
|
|
broken across several lines. This break should occur after |
208 |
|
|
an operator and the next line should be indented further |
209 |
|
|
than the code which will follow in the body. |
210 |
|
|
|
211 |
|
|
Exceptions |
212 |
|
|
---------- |
213 |
|
|
|
214 |
|
|
Exceptions should be used where necessary, and these should |
215 |
|
|
almost always be checked exceptions. Instead of throwing the |
216 |
|
|
basic Exception classes, sub-classes should be made with |
217 |
|
|
more meaningful names, although they need not provide any |
218 |
|
|
further functionality. Appropriate catch statements should |
219 |
|
|
be put in place to allow the program to recover if need be. |
220 |
|
|
|
221 |
|
|
Access Control |
222 |
|
|
-------------- |
223 |
|
|
|
224 |
|
|
The following rules should be adhered to, ensuring that |
225 |
|
|
access control is correctly implemented and used. |
226 |
|
|
|
227 |
|
|
- Attributes of an object should be declared as private, |
228 |
|
|
rather than public, package or protected. The only |
229 |
|
|
exception is in the use of static final variables which |
230 |
|
|
cannot be changed anyway. |
231 |
|
|
|
232 |
|
|
- Accessors may be used to grant access to attributes of a |
233 |
|
|
primitive type, although much more care must be taken |
234 |
|
|
when returning references to attributes of object types |
235 |
|
|
since this could lead to possible bypassing of any |
236 |
|
|
mutators. |
237 |
|
|
|
238 |
|
|
- Mutators should be protected unless they specifically |
239 |
|
|
need to be public. A mutator can ensure that values are |
240 |
|
|
checked before being put in to the private attribute. |
241 |
|
|
|
242 |
|
|
- Methods commonly have public access, although private |
243 |
|
|
access should be considered if the method is to be used |
244 |
|
|
only by the class in which it is placed. |
245 |
|
|
|
246 |
|
|
- Package visibility should also be considered if the use |
247 |
|
|
of packages is implemented. Again, each method's use |
248 |
|
|
should be considered carefully, and an appropriate |
249 |
|
|
access control method chosen. |
250 |
|
|
|
251 |
|
|
- Protected visibility is unlikely to be used as sub- |
252 |
|
|
classing any of the classes is unlikely, although if |
253 |
|
|
such a situation should arise it should be carefully |
254 |
|
|
considered. |
255 |
|
|
|
256 |
|
|
When considering what type of access control to use it is |
257 |
|
|
best to be more restrictive than lenient. If a method's |
258 |
|
|
visibility is too restrictive then it will be identified |
259 |
|
|
more quickly than if the reverse were to happen. |
260 |
|
|
|
261 |
|
|
Imports |
262 |
|
|
------- |
263 |
|
|
|
264 |
|
|
The use if the * form of import should be avoided. Each |
265 |
|
|
class should be specifically imported as required, and any |
266 |
|
|
unused imports should be removed if they are no longer |
267 |
|
|
needed. This makes it clear as to exactly what the class is |
268 |
|
|
using. |
269 |
|
|
|
270 |
|
|
|
271 |
|
|
Overall Class Layout |
272 |
|
|
-------------------- |
273 |
|
|
|
274 |
|
|
The overall layout of a class is important, especially when |
275 |
|
|
it comes to reviewing the code at a later stage. Here I will |
276 |
|
|
outline the order in which methods and attributes should |
277 |
|
|
appear in a class. This psuedo class shows where everything |
278 |
|
|
should appear, including imports and package declarations. |
279 |
|
|
Commenting will be dealt with in a further section. |
280 |
|
|
|
281 |
|
|
// package declaration |
282 |
|
|
package server |
283 |
|
|
// imports |
284 |
|
|
import java.util.LinkedList |
285 |
|
|
import java.io.InputStream |
286 |
|
|
|
287 |
|
|
class MyDummyClass { |
288 |
|
|
|
289 |
|
|
// attributes such as "magic numbers" should be first |
290 |
|
|
public static final int S = 1; |
291 |
|
|
public static final int E = 3; |
292 |
|
|
|
293 |
|
|
// no-args constructor first |
294 |
|
|
public MyDummyClass(){ |
295 |
|
|
. . . |
296 |
|
|
} |
297 |
|
|
|
298 |
|
|
// further constructors follow |
299 |
|
|
public MyDummyClass(int x){ |
300 |
|
|
. . . |
301 |
|
|
} |
302 |
|
|
|
303 |
|
|
// public methods |
304 |
|
|
public void myMethod(){ |
305 |
|
|
. . . |
306 |
|
|
} |
307 |
|
|
|
308 |
|
|
// private methods |
309 |
|
|
private void anotherMethod(){ |
310 |
|
|
. . . |
311 |
|
|
} |
312 |
|
|
|
313 |
|
|
// accessors & mutators |
314 |
|
|
public int getMyVar(){ |
315 |
|
|
. . . |
316 |
|
|
} |
317 |
|
|
|
318 |
|
|
// private attributes |
319 |
|
|
private int myVar = 5; |
320 |
|
|
} |
321 |
|
|
|
322 |
|
|
This layout should be followed in every source file |
323 |
|
|
generated. The reason for this structure is that reading |
324 |
|
|
downwards you reach the most used methods and attributes |
325 |
|
|
first. The exception are the public static final attributes |
326 |
|
|
which are put first to allow them to easily be identified |
327 |
|
|
and changed at a later date. |
328 |
|
|
|
329 |
|
|
Naming Conventions |
330 |
|
|
------------------ |
331 |
|
|
|
332 |
|
|
Although this section has been covered throughout the last |
333 |
|
|
section, I think it is key that the various naming |
334 |
|
|
conventions be clearly identified here. Examples are given |
335 |
|
|
for each convention. |
336 |
|
|
|
337 |
|
|
- Packages |
338 |
|
|
eg. demo.package |
339 |
|
|
Package names should all be in lower case. |
340 |
|
|
|
341 |
|
|
- Files |
342 |
|
|
eg. ClassName.java |
343 |
|
|
The Java convention is that files have the same name |
344 |
|
|
as the class they contain, and the compiler enforces |
345 |
|
|
this. |
346 |
|
|
|
347 |
|
|
- Classes |
348 |
|
|
eg. ClassName |
349 |
|
|
Class names should begin with a capital letter and |
350 |
|
|
each new word within the name should begin with a |
351 |
|
|
capital letter. |
352 |
|
|
|
353 |
|
|
- Exception Classes |
354 |
|
|
eg. ClassNameException |
355 |
|
|
Exception classes should follow the same rule as |
356 |
|
|
normal classes, but should end with the word |
357 |
|
|
Exception. |
358 |
|
|
|
359 |
|
|
- Constants or "magic numbers" (public) |
360 |
|
|
eg. MY_STATIC_VARIABLE |
361 |
|
|
These public static variables should always be in |
362 |
|
|
upper-case. An underscore could be used if required to |
363 |
|
|
make the name more readable. |
364 |
|
|
|
365 |
|
|
- Methods |
366 |
|
|
eg. methodName() |
367 |
|
|
Methods should begin with a lower case letter and each |
368 |
|
|
new word within the name should begin with a capital |
369 |
|
|
letter. |
370 |
|
|
|
371 |
|
|
- Variables and Attributes |
372 |
|
|
eg. variableName |
373 |
|
|
Both variables and attributes should being with a |
374 |
|
|
lower case letter and each new word within the name |
375 |
|
|
should begin with a capital letter - exactly the same |
376 |
|
|
as methods. |
377 |
|
|
|
378 |
|
|
- Accessors |
379 |
|
|
eg. getVariable() |
380 |
|
|
Accessors should follow the same rules as a normal |
381 |
|
|
method, but should be named after the variable which |
382 |
|
|
they provide access to. |
383 |
|
|
|
384 |
|
|
- Mutators |
385 |
|
|
eg. setVariable(...) |
386 |
|
|
Mutators should follow the same rules as a normal |
387 |
|
|
method, but should be named after the variable to |
388 |
|
|
which they control access. |
389 |
|
|
|
390 |
|
|
|
391 |
|
|
Commenting & Documentation |
392 |
|
|
========================== |
393 |
|
|
|
394 |
|
|
All programs should be properly and thoroughly documented. |
395 |
|
|
The javadoc tool provides a convention for documenting code |
396 |
|
|
and facilitates the automatic generation of program |
397 |
|
|
documentation. |
398 |
|
|
|
399 |
|
|
Classes and Interfaces |
400 |
|
|
---------------------- |
401 |
|
|
|
402 |
|
|
Each class should have a javadoc comment block at the start |
403 |
|
|
of the code. This block of comment should be placed in the |
404 |
|
|
standard javadoc style /** .. **/ immediately preceding the |
405 |
|
|
class header. Package declarations and imports will appear |
406 |
|
|
before this initial documentation. Within this section the |
407 |
|
|
following items should be included: |
408 |
|
|
|
409 |
|
|
- Class Name |
410 |
|
|
- Description of the class and it's use |
411 |
|
|
- Revision History |
412 |
|
|
- Author(s) - javadoc tag |
413 |
|
|
- Version Number - javadoc tag |
414 |
|
|
|
415 |
|
|
It is important to note that as well as the code being read |
416 |
|
|
by hand, these comments will also be used to generate |
417 |
|
|
information about the class on a webpage using javadoc. |
418 |
|
|
Bearing this in mind it may be necessary to use HTML tags to |
419 |
|
|
layout the comments, although these should be neatly done so |
420 |
|
|
as not to make the comments unreadable in the source code. |
421 |
|
|
|
422 |
|
|
Various javadoc tags should be used to give specific |
423 |
|
|
information to the javadoc engine. These should be placed on |
424 |
|
|
a separate line. |
425 |
|
|
|
426 |
|
|
- @author <author name> |
427 |
|
|
The name of the author, preferably with e-mail address. |
428 |
|
|
|
429 |
|
|
- @version <version number> |
430 |
|
|
The version number of the code, with date. |
431 |
|
|
|
432 |
|
|
This is an example of a class header, which contains all of |
433 |
|
|
the above items. |
434 |
|
|
|
435 |
|
|
/** |
436 |
|
|
* MyClass <br> |
437 |
|
|
* |
438 |
|
|
* This class is merely for illustrative purposes. <br> |
439 |
|
|
* |
440 |
|
|
* Revision History:<br> |
441 |
|
|
* 1.1 - Added javadoc headers <br> |
442 |
|
|
* 1.0 - Original release<br> |
443 |
|
|
* |
444 |
|
|
* @author T.D.Bishop |
445 |
|
|
* @version 1.1, 19/04/2000 |
446 |
|
|
*/ |
447 |
|
|
public class MyClass { |
448 |
|
|
. . . |
449 |
|
|
} |
450 |
|
|
|
451 |
|
|
Methods |
452 |
|
|
------- |
453 |
|
|
|
454 |
|
|
Methods should contain a similar javadoc comment to classes, |
455 |
|
|
which should be places between /** .. **/ marks immediately |
456 |
|
|
preceding the method header. It may not be necessary to do |
457 |
|
|
this for all methods, but constructors and major methods |
458 |
|
|
certainly should have them, whilst accessors and mutators |
459 |
|
|
can have a more cut down version. The following items should |
460 |
|
|
be included: |
461 |
|
|
|
462 |
|
|
- Purpose of method |
463 |
|
|
- Argument descriptions |
464 |
|
|
- Result descriptions |
465 |
|
|
- Exceptions thrown |
466 |
|
|
|
467 |
|
|
There are also javadoc tags that can be used specifically |
468 |
|
|
for method comments. In a similar way to class comments each |
469 |
|
|
begins with an @ and should be placed on a line of it's own. |
470 |
|
|
|
471 |
|
|
- @param <param name> <param description> |
472 |
|
|
Should be specified for each parameter that a method |
473 |
|
|
takes, with it's name and purpose. |
474 |
|
|
|
475 |
|
|
- @return <description> |
476 |
|
|
Describes the result returned by the method. |
477 |
|
|
|
478 |
|
|
- @throws <exception name> <reason for being thrown> |
479 |
|
|
Gives the name of any exceptions that may be thrown, and |
480 |
|
|
why. |
481 |
|
|
|
482 |
|
|
Here is an example of a method header, showing the above in |
483 |
|
|
use. |
484 |
|
|
|
485 |
|
|
/** |
486 |
|
|
* This method has no use, and it just illustrative. <br> |
487 |
|
|
* Although it does suggest adding the two parameters |
488 |
|
|
* together ! <br> |
489 |
|
|
* |
490 |
|
|
* @param first The first number to be added |
491 |
|
|
* @param second The second number to be added |
492 |
|
|
* @return The sum of the two parameters |
493 |
|
|
* @throws BadException if something goes very wrong ! |
494 |
|
|
*/ |
495 |
|
|
public int sumNumbers(int first, int second) throws |
496 |
|
|
BadException{ |
497 |
|
|
. . . |
498 |
|
|
} |
499 |
|
|
|
500 |
|
|
Attributes and Variables |
501 |
|
|
------------------------ |
502 |
|
|
|
503 |
|
|
Attributes and variables require far less commenting than |
504 |
|
|
classes and methods. They should simply contain a brief |
505 |
|
|
description of what they are used for, and could possibly |
506 |
|
|
refer to any accessors or mutators that allow access to |
507 |
|
|
them. Attributes that are public static final should have a |
508 |
|
|
bit more detailed information as other classes may wish to |
509 |
|
|
use them. Here is a basic example: |
510 |
|
|
|
511 |
|
|
/** |
512 |
|
|
* This attribute represents the byte value used to start |
513 |
|
|
* a packet. |
514 |
|
|
*/ |
515 |
|
|
public static final int ST = 2; |
516 |
|
|
|
517 |
|
|
|
518 |
|
|
General Commenting |
519 |
|
|
------------------ |
520 |
|
|
|
521 |
|
|
It is often necessary to add comments within the body of a |
522 |
|
|
method. It is preferable to comment in blocks, rather than |
523 |
|
|
individually on each line. Likewise it is not necessary to |
524 |
|
|
comment code that is obvious in it's purpose. Both single |
525 |
|
|
line comments (using //) and multi-line comments (using /* |
526 |
|
|
.. */) are acceptable. This is an example of the layout of |
527 |
|
|
the two methods: |
528 |
|
|
|
529 |
|
|
int index = 1; // index of starting point |
530 |
|
|
|
531 |
|
|
/* This is a mult-line |
532 |
|
|
* comment, and spans |
533 |
|
|
* several lines ! |
534 |
|
|
*/ |
535 |
|
|
|
536 |
|
|
|
537 |
|
|
General Recommendations |
538 |
|
|
======================= |
539 |
|
|
|
540 |
|
|
Threading |
541 |
|
|
--------- |
542 |
|
|
|
543 |
|
|
Threading is a complicated issue, so I will only briefly |
544 |
|
|
mention it. The main issue is using the synchronized |
545 |
|
|
modifier to prevent deadlock over the system when accessing |
546 |
|
|
shared objects. It is important not to overuse this, as it |
547 |
|
|
can cause unnecessary deadlock. Use it only when there is a |
548 |
|
|
clear need to do so. |
549 |
|
|
|
550 |
|
|
Class Design |
551 |
|
|
------------ |
552 |
|
|
|
553 |
|
|
Class design should be done in a way that reduces coupling |
554 |
|
|
as far as possible. Simply dividing the overall system into |
555 |
|
|
clear defined parts is a good way to start this. |
556 |
|
|
|
557 |
|
|
Platform |
558 |
|
|
-------- |
559 |
|
|
|
560 |
|
|
This document refers to the Java 2 platform (or JDK 1.2). |
561 |
|
|
Everything mentioned in this document is based upon this |
562 |
|
|
platform and may therefore be out of date in future versions |
563 |
|
|
of the Java platform. |
564 |
|
|
|