-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchapter-8.txt
4074 lines (2517 loc) · 195 KB
/
chapter-8.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Chapter 8. Classes
Table of Contents
8.1. Class Declarations
8.1.1. Class Modifiers
8.1.1.1. abstract Classes
8.1.1.2. sealed, non-sealed, and final Classes
8.1.1.3. strictfp Classes
8.1.1.4. static Classes
8.1.2. Generic Classes and Type Parameters
8.1.3. Inner Classes and Enclosing Instances
8.1.4. Superclasses and Subclasses
8.1.5. Superinterfaces
8.1.6. Permitted Direct Subclasses
8.1.7. Class Body and Member Declarations
8.2. Class Members
8.3. Field Declarations
8.3.1. Field Modifiers
8.3.1.1. static Fields
8.3.1.2. final Fields
8.3.1.3. transient Fields
8.3.1.4. volatile Fields
8.3.2. Field Initialization
8.3.3. Restrictions on Field References in Initializers
8.4. Method Declarations
8.4.1. Formal Parameters
8.4.2. Method Signature
8.4.3. Method Modifiers
8.4.3.1. abstract Methods
8.4.3.2. static Methods
8.4.3.3. final Methods
8.4.3.4. native Methods
8.4.3.5. strictfp Methods
8.4.3.6. synchronized Methods
8.4.4. Generic Methods
8.4.5. Method Result
8.4.6. Method Throws
8.4.7. Method Body
8.4.8. Inheritance, Overriding, and Hiding
8.4.8.1. Overriding (by Instance Methods)
8.4.8.2. Hiding (by Class Methods)
8.4.8.3. Requirements in Overriding and Hiding
8.4.8.4. Inheriting Methods with Override-Equivalent Signatures
8.4.9. Overloading
8.5. Member Class and Interface Declarations
8.6. Instance Initializers
8.7. Static Initializers
8.8. Constructor Declarations
8.8.1. Formal Parameters
8.8.2. Constructor Signature
8.8.3. Constructor Modifiers
8.8.4. Generic Constructors
8.8.5. Constructor Throws
8.8.6. The Type of a Constructor
8.8.7. Constructor Body
8.8.7.1. Explicit Constructor Invocations
8.8.8. Constructor Overloading
8.8.9. Default Constructor
8.8.10. Preventing Instantiation of a Class
8.9. Enum Classes
8.9.1. Enum Constants
8.9.2. Enum Body Declarations
8.9.3. Enum Members
8.10. Record Classes
8.10.1. Record Components
8.10.2. Record Body Declarations
8.10.3. Record Members
8.10.4. Record Constructor Declarations
8.10.4.1. Normal Canonical Constructors
8.10.4.2. Compact Canonical Constructors
A class declaration defines a new class and describes how it is implemented (§8.1).
A top level class (§7.6) is a class declared directly in a compilation unit.
A nested class is any class whose declaration occurs within the body of another class or interface declaration. A nested class may be a member class (§8.5, §9.5), a local class (§14.3), or an anonymous class (§15.9.5).
Some kinds of nested class are an inner class (§8.1.3), which is a class that can refer to enclosing class instances, local variables, and type variables.
An enum class (§8.9) is a class declared with abbreviated syntax that defines a small set of named class instances.
A record class (§8.10) is a class declared with abbreviated syntax that defines a simple aggregate of values.
This chapter discusses the common semantics of all classes. Details that are specific to particular kinds of classes are discussed in the sections dedicated to these constructs.
A class may be declared public (§8.1.1) so it can be referred to from code in any package of its module and potentially from code in other modules.
A class may be declared abstract (§8.1.1.1), and must be declared abstract if it is incompletely implemented; such a class cannot be instantiated, but can be extended by subclasses. The degree to which a class can be extended can be controlled explicitly (§8.1.1.2): it may be declared sealed to limit its subclasses, or it may be declared final to ensure no subclasses. Each class except Object is an extension of (that is, a subclass of) a single existing class (§8.1.4) and may implement interfaces (§8.1.5).
A class may be generic (§8.1.2), that is, its declaration may introduce type variables whose bindings differ among different instances of the class.
Class declarations may be decorated with annotations (§9.7) just like any other kind of declaration.
The body of a class declares members (fields, methods, classes, and interfaces), instance and static initializers, and constructors (§8.1.7). The scope (§6.3) of a member (§8.2) is the entire body of the declaration of the class to which the member belongs. Field, method, member class, member interface, and constructor declarations may include the access modifiers public, protected, or private (§6.6). The members of a class include both declared and inherited members (§8.2). Newly declared fields can hide fields declared in a superclass or superinterface. Newly declared member classes and member interfaces can hide member classes and member interfaces declared in a superclass or superinterface. Newly declared methods can hide, implement, or override methods declared in a superclass or superinterface.
Field declarations (§8.3) describe class variables, which are incarnated once, and instance variables, which are freshly incarnated for each instance of the class. A field may be declared final (§8.3.1.2), in which case it can be assigned to only once. Any field declaration may include an initializer.
Member class declarations (§8.5) describe nested classes that are members of the surrounding class. Member classes may be static, in which case they have no access to the instance variables of the surrounding class; or they may be inner classes.
Member interface declarations (§8.5) describe nested interfaces that are members of the surrounding class.
Method declarations (§8.4) describe code that may be invoked by method invocation expressions (§15.12). A class method is invoked relative to the class; an instance method is invoked with respect to some particular object that is an instance of a class. A method whose declaration does not indicate how it is implemented must be declared abstract. A method may be declared final (§8.4.3.3), in which case it cannot be hidden or overridden. A method may be implemented by platform-dependent native code (§8.4.3.4). A synchronized method (§8.4.3.6) automatically locks an object before executing its body and automatically unlocks the object on return, as if by use of a synchronized statement (§14.19), thus allowing its activities to be synchronized with those of other threads (§17 (Threads and Locks)).
Method names may be overloaded (§8.4.9).
Instance initializers (§8.6) are blocks of executable code that may be used to help initialize an instance when it is created (§15.9).
Static initializers (§8.7) are blocks of executable code that may be used to help initialize a class.
Constructors (§8.8) are similar to methods, but cannot be invoked directly by a method call; they are used to initialize new class instances. Like methods, they may be overloaded (§8.8.8).
8.1. Class Declarations
A class declaration specifies a class.
There are three kinds of class declarations: normal class declarations, enum declarations (§8.9), and record declarations (§8.10).
ClassDeclaration:
NormalClassDeclaration
EnumDeclaration
RecordDeclaration
NormalClassDeclaration:
{ClassModifier} class TypeIdentifier [TypeParameters] [ClassExtends] [ClassImplements] [ClassPermits] ClassBody
A class is also implicitly declared by a class instance creation expression (§15.9.5) and an enum constant that ends with a class body (§8.9.1).
The TypeIdentifier in a class declaration specifies the name of the class.
It is a compile-time error if a class has the same simple name as any of its enclosing classes or interfaces.
The scope and shadowing of a class declaration is specified in §6.3 and §6.4.1.
8.1.1. Class Modifiers
A class declaration may include class modifiers.
ClassModifier:
(one of)
Annotation public protected private
abstract static final sealed non-sealed strictfp
The rules concerning annotation modifiers for a class declaration are specified in §9.7.4 and §9.7.5.
The access modifier public (§6.6) pertains only to top level classes (§7.6) and member classes (§8.5, §9.5), not to local classes (§14.3) or anonymous classes (§15.9.5).
The access modifiers protected and private pertain only to member classes.
The modifier static pertains only to member classes and local classes.
It is a compile-time error if the same keyword appears more than once as a modifier for a class declaration, or if a class declaration has more than one of the access modifiers public, protected, and private.
It is a compile-time error if a class declaration has more than one of the modifiers sealed, non-sealed, and final.
If two or more (distinct) class modifiers appear in a class declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for ClassModifier.
8.1.1.1. abstract Classes
An abstract class is a class that is incomplete, or to be considered incomplete.
It is a compile-time error if an attempt is made to create an instance of an abstract class using a class instance creation expression (§15.9.1).
A subclass of an abstract class that is not itself abstract may be instantiated, resulting in the execution of a constructor for the abstract class and, therefore, the execution of the field initializers for instance variables of that class.
A normal class may have abstract methods, that is, methods that are declared but not yet implemented (§8.4.3.1), only if it is an abstract class. It is a compile-time error if a normal class that is not abstract has an abstract method.
A class C has abstract methods if either of the following is true:
Any of the member methods (§8.2) of C - either declared or inherited - is abstract.
Any of C's superclasses has an abstract method declared with package access, and there exists no method that overrides the abstract method from C or from a superclass of C.
It is a compile-time error to declare an abstract class type such that it is not possible to create a subclass that implements all of its abstract methods. This situation can occur if the class would have as members two abstract methods that have the same method signature (§8.4.2) but return types for which no type is return-type-substitutable with both (§8.4.5).
Example 8.1.1.1-1. Abstract Class Declaration
abstract class Point {
int x = 1, y = 1;
void move(int dx, int dy) {
x += dx;
y += dy;
alert();
}
abstract void alert();
}
abstract class ColoredPoint extends Point {
int color;
}
class SimplePoint extends Point {
void alert() { }
}
Here, a class Point is declared that must be declared abstract, because it contains a declaration of an abstract method named alert. The subclass of Point named ColoredPoint inherits the abstract method alert, so it must also be declared abstract. On the other hand, the subclass of Point named SimplePoint provides an implementation of alert, so it need not be abstract.
The statement:
Point p = new Point();
would result in a compile-time error; the class Point cannot be instantiated because it is abstract. However, a Point variable could correctly be initialized with a reference to any subclass of Point, and the class SimplePoint is not abstract, so the statement:
Point p = new SimplePoint();
would be correct. Instantiation of a SimplePoint causes the default constructor and field initializers for x and y of Point to be executed.
Example 8.1.1.1-2. Abstract Class Declaration that Prohibits Subclasses
interface Colorable {
void setColor(int color);
}
abstract class Colored implements Colorable {
public abstract int setColor(int color);
}
These declarations result in a compile-time error: it would be impossible for any subclass of class Colored to provide an implementation of a method named setColor, taking one argument of type int, that can satisfy both abstract method specifications, because the one in interface Colorable requires the same method to return no value, while the one in class Colored requires the same method to return a value of type int (§8.4).
A class type should be declared abstract only if the intent is that subclasses can be created to complete the implementation. If the intent is simply to prevent instantiation of a class, the proper way to express this is to declare a constructor (§8.8.10) of no arguments, make it private, never invoke it, and declare no other constructors. A class of this form usually contains class methods and variables.
The class Math is an example of a class that cannot be instantiated; its declaration looks like this:
public final class Math {
private Math() { } // never instantiate this class
. . . declarations of class variables and methods . . .
}
8.1.1.2. sealed, non-sealed, and final Classes
A class can be declared sealed if all its direct subclasses are known when the class is declared (§8.1.6), and no other direct subclasses are desired or required.
Explicit and exhaustive control over a class's direct subclasses is useful when the class hierarchy is used to model the kinds of values in a domain, rather than as a mechanism for code inheritance and reuse. The direct subclasses may themselves be declared sealed in order to further control the class hierarchy.
A class can be declared final if its definition is complete and no subclasses are desired or required.
It is a compile-time error if a class is declared both final and abstract, because the implementation of such a class could never be completed (§8.1.1.1).
Because a final class never has any subclasses, the methods of a final class are never overridden (§8.4.8.1).
A class is freely extensible if its direct superclass is not sealed (§8.1.4), and none of its direct superinterfaces are sealed (§8.1.5), and it is neither sealed nor final itself.
A class that has a sealed direct superclass or a sealed direct superinterface is freely extensible if and only if it is declared non-sealed.
It is a compile-time error if a class has a sealed direct superclass or a sealed direct superinterface, and is not declared final, sealed, or non-sealed either explicitly or implicitly.
Thus, an effect of the sealed keyword is to force all direct subclasses to explicitly declare whether they are final, sealed, or non-sealed. This avoids accidentally exposing a sealed class hierarchy to unwanted subclassing.
An enum class is either implicitly final or implicitly sealed, so it can implement a sealed interface. Similarly, a record class is implicitly final, so it can also implement a sealed interface.
It is a compile-time error if a class is declared non-sealed but has neither a sealed direct superclass nor a sealed direct superinterface.
Thus, a subclass of a non-sealed class cannot itself be declared non-sealed.
8.1.1.3. strictfp Classes
The strictfp modifier on a class declaration is obsolete and should not be used in new code. Its presence or absence has no effect at compile time or run time.
8.1.1.4. static Classes
The static modifier specifies that a nested class is not an inner class (§8.1.3). Just as a static method of a class has no current instance of the class in its body, a static nested class has no immediately enclosing instance in its body.
References from a static nested class to type parameters, instance variables, local variables, formal parameters, exception parameters, or instance methods of lexically enclosing class, interface, or method declarations are disallowed (§6.5.5.1, §6.5.6.1, and §15.12.3).
The static modifier does not pertain to all nested classes. It pertains only to member classes, whose declarations may use the static modifier, and not to local classes or anonymous classes, whose declarations may not use the static modifier (§14.3, §15.9.5). However, some local classes are implicitly static, namely local enum classes and local record classes, because all nested enum classes and nested record classes are implicitly static (§8.9, §8.10).
8.1.2. Generic Classes and Type Parameters
A class is generic if the class declaration declares one or more type variables (§4.4).
These type variables are known as the type parameters of the class. The type parameter section follows the class name and is delimited by angle brackets.
TypeParameters:
< TypeParameterList >
TypeParameterList:
TypeParameter {, TypeParameter}
The following productions from §4.4 are shown here for convenience:
TypeParameter:
{TypeParameterModifier} TypeIdentifier [TypeBound]
TypeParameterModifier:
Annotation
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
AdditionalBound:
& InterfaceType
The rules concerning annotation modifiers for a type parameter declaration are specified in §9.7.4 and §9.7.5.
In a class's type parameter section, a type variable T directly depends on a type variable S if S is the bound of T, while T depends on S if either T directly depends on S or T directly depends on a type variable U that depends on S (using this definition recursively).
It is a compile-time error if a type variable in a class's type parameter section depends on itself.
The scope and shadowing of a class's type parameter is specified in §6.3 and §6.4.1.
References to a class's type parameter from a static context or a nested class or interface are restricted, as specified in §6.5.5.1.
A generic class declaration defines a set of parameterized types (§4.5), one for each possible parameterization of the type parameter section by type arguments. All of these parameterized types share the same class at run time.
For instance, executing the code:
Vector<String> x = new Vector<String>();
Vector<Integer> y = new Vector<Integer>();
boolean b = x.getClass() == y.getClass();
will result in the variable b holding the value true.
It is a compile-time error if a generic class is a direct or indirect subclass of Throwable (§11.1.1).
This restriction is needed since the catch mechanism of the Java Virtual Machine works only with non-generic classes.
Example 8.1.2-1. Mutually Recursive Type Variable Bounds
interface ConvertibleTo<T> {
T convert();
}
class ReprChange<T extends ConvertibleTo<S>,
S extends ConvertibleTo<T>> {
T t;
void set(S s) { t = s.convert(); }
S get() { return t.convert(); }
}
Example 8.1.2-2. Nested Generic Classes
class Seq<T> {
T head;
Seq<T> tail;
Seq() { this(null, null); }
Seq(T head, Seq<T> tail) {
this.head = head;
this.tail = tail;
}
boolean isEmpty() { return tail == null; }
class Zipper<S> {
Seq<Pair<T,S>> zip(Seq<S> that) {
if (isEmpty() || that.isEmpty()) {
return new Seq<Pair<T,S>>();
} else {
Seq<T>.Zipper<S> tailZipper =
tail.new Zipper<S>();
return new Seq<Pair<T,S>>(
new Pair<T,S>(head, that.head),
tailZipper.zip(that.tail));
}
}
}
}
class Pair<T, S> {
T fst; S snd;
Pair(T f, S s) { fst = f; snd = s; }
}
class Test {
public static void main(String[] args) {
Seq<String> strs =
new Seq<String>(
"a",
new Seq<String>("b",
new Seq<String>()));
Seq<Number> nums =
new Seq<Number>(
new Integer(1),
new Seq<Number>(new Double(1.5),
new Seq<Number>()));
Seq<String>.Zipper<Number> zipper =
strs.new Zipper<Number>();
Seq<Pair<String,Number>> combined =
zipper.zip(nums);
}
}
8.1.3. Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly static.
An inner class is one of the following:
a member class that is not explicitly or implicitly static (§8.5)
a local class that is not implicitly static (§14.3)
an anonymous class (§15.9.5)
The following nested classes are implicitly static, so are not inner classes:
a member enum class (§8.9)
a local enum class (§14.3)
a member record class (§8.10)
a local record class (§14.3)
a member class of an interface (§9.5)
All of the rules that apply to nested classes apply to inner classes. In particular, an inner class may declare and inherit static members (§8.2), and declare static initializers (§8.7), even though the inner class itself is not static.
There are no "inner interfaces" because every nested interface is implicitly static (§9.1.1.3).
Example 8.1.3-1. Inner Class Declarations and Static Members
class HasStatic {
static int j = 100;
}
class Outer {
class Inner extends HasStatic {
static {
System.out.println("Hello from Outer.Inner");
}
static int x = 3;
static final int y = 4;
static void hello() {
System.out.println("Hello from Outer.Inner.hello");
}
static class VeryNestedButNotInner
extends NestedButNotInner {}
}
static class NestedButNotInner {
int z = Inner.x;
}
interface NeverInner {} // Implicitly static, so never inner
}
Prior to Java SE 16, an inner class could not declare static initializers, and could only declare static members that were constant variables (§4.12.4).
A construct (statement, local variable declaration statement, local class declaration, local interface declaration, or expression) occurs in a static context if the innermost:
method declaration,
field declaration,
constructor declaration,
instance initializer,
static initializer, or
explicit constructor invocation statement
which encloses the construct is one of the following:
a static method declaration (§8.4.3.2, §9.4)
a static field declaration (§8.3.1.1, §9.3)
a static initializer (§8.7)
an explicit constructor invocation statement (§8.8.7.1)
Note that a construct which appears in a constructor declaration or an instance initializer does not occur in a static context.
The purpose of a static context is to demarcate code that must not refer explicitly or implicitly to the current instance of the class whose declaration lexically encloses the static context. Consequently, code that occurs in a static context is restricted in the following ways:
this expressions (both unqualified and qualified) are disallowed (§15.8.3, §15.8.4).
Field accesses, method invocations, and method references may not be qualified by super (§15.11.2, §15.12.3, §15.13.1).
Unqualified references to instance variables of any lexically enclosing class or interface declaration are disallowed (§6.5.6.1).
Unqualified invocations of instance methods of any lexically enclosing class or interface declaration are disallowed (§15.12.3).
References to type parameters of any lexically enclosing class or interface declarations are disallowed (§6.5.5.1).
References to type parameters, local variables, formal parameters, and exception parameters declared by methods or constructors of any lexically enclosing class or interface declaration that is outside the immediately enclosing class or interface declaration are disallowed (§6.5.5.1, §6.5.6.1).
Declarations of local normal classes (as opposed to local enum classes) and declarations of anonymous classes both specify classes that are inner, yet when instantiated have no immediately enclosing instances (§15.9.2).
Class instance creation expressions that instantiate inner member classes must be qualified (§15.9).
An inner class C is a direct inner class of a class or interface O if O is the immediately enclosing class or interface declaration of C and the declaration of C does not occur in a static context.
If an inner class is a local class or an anonymous class, it may be declared in a static context, and in that case is not considered an inner class of any enclosing class or interface.
A class C is an inner class of class or interface O if it is either a direct inner class of O or an inner class of an inner class of O.
It is unusual, but possible, for the immediately enclosing class or interface declaration of an inner class to be an interface. This only occurs if the class is a local or anonymous class declared in a default or static method body (§9.4).
A class or interface O is the zeroth lexically enclosing class or interface declaration of itself.
A class O is the n'th lexically enclosing class declaration of a class C if it is the immediately enclosing class declaration of the n-1'th lexically enclosing class declaration of C.
An instance i of a direct inner class C of a class or interface O is associated with an instance of O, known as the immediately enclosing instance of i. The immediately enclosing instance of an object, if any, is determined when the object is created (§15.9.2).
An object o is the zeroth lexically enclosing instance of itself.
An object o is the n'th lexically enclosing instance of an instance i if it is the immediately enclosing instance of the n-1'th lexically enclosing instance of i.
An instance of an inner local class or an anonymous class whose declaration occurs in a static context has no immediately enclosing instance. Also, an instance of a static nested class (§8.1.1.4) has no immediately enclosing instance.
For every superclass S of C which is itself a direct inner class of a class or interface SO, there is an instance of SO associated with i, known as the immediately enclosing instance of i with respect to S. The immediately enclosing instance of an object with respect to its class' direct superclass, if any, is determined when the superclass constructor is invoked via an explicit constructor invocation statement (§8.8.7.1).
When an inner class (whose declaration does not occur in a static context) refers to an instance variable that is a member of a lexically enclosing class or interface declaration, the variable of the corresponding lexically enclosing instance is used.
Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be final or effectively final (§4.12.4), as specified in §6.5.6.1.
Any local variable used but not declared in an inner class must be definitely assigned (§16 (Definite Assignment)) before the body of the inner class, or a compile-time error occurs.
Similar rules on variable use apply in the body of a lambda expression (§15.27.2).
A blank final field (§4.12.4) of a lexically enclosing class or interface declaration may not be assigned within an inner class, or a compile-time error occurs.
Example 8.1.3-2. Inner Class Declarations
class Outer {
int i = 100;
static void classMethod() {
final int l = 200;
class LocalInStaticContext {
int k = i; // Compile-time error
int m = l; // OK
}
}
void foo() {
class Local { // A local class
int j = i;
}
}
}
The declaration of class LocalInStaticContext occurs in a static context due to being within the static method classMethod. Instance variables of class Outer are not available within the body of a static method. In particular, instance variables of Outer are not available inside the body of LocalInStaticContext. However, local variables from the surrounding method may be referred to without error (provided they are declared final or are effectively final).
Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing class declaration. An instance variable is always defined with respect to an instance. In the case of instance variables of an enclosing class declaration, the instance variable must be defined with respect to an enclosing instance of the inner class. For example, the class Local above has an enclosing instance of class Outer. As a further example:
class WithDeepNesting {
boolean toBe;
WithDeepNesting(boolean b) { toBe = b; }
class Nested {
boolean theQuestion;
class DeeplyNested {
DeeplyNested(){
theQuestion = toBe || !toBe;
}
}
}
}
Here, every instance of WithDeepNesting.Nested.DeeplyNested has an enclosing instance of class WithDeepNesting.Nested (its immediately enclosing instance) and an enclosing instance of class WithDeepNesting (its 2nd lexically enclosing instance).
8.1.4. Superclasses and Subclasses
The optional extends clause in a normal class declaration specifies the direct superclass type of the class being declared.
ClassExtends:
extends ClassType
The extends clause must not appear in the definition of the class Object, or a compile-time error occurs, because it is the primordial class and has no direct superclass type.
The ClassType must name an accessible class (§6.6), or a compile-time error occurs.
It is a compile-time error if the ClassType names a class that is sealed (§8.1.1.2) and the class being declared is not a permitted direct subclass of the named class (§8.1.6).
It is a compile-time error if the ClassType names a class that is final, because final classes are not allowed to have subclasses (§8.1.1.2).
It is a compile-time error if the ClassType names the class Enum, which can only be extended by an enum class (§8.9), or names the class Record, which can only be extended by a record class (§8.10).
If the ClassType has type arguments, it must denote a well-formed parameterized type (§4.5), and none of the type arguments may be wildcard type arguments, or a compile-time error occurs.
The direct superclass type of a class whose declaration lacks an extends clause is as follows:
The class Object has no direct superclass type.
For a class other than Object with a normal class declaration, the direct superclass type is Object.
For an enum class E, the direct superclass type is Enum<E>.
For a record class R, the direct superclass type is Record.
For an anonymous class, the direct superclass type is defined in §15.9.5.
The direct superclass of a class is the class named by its direct superclass type. The direct superclass is important because its implementation is used to derive the implementation of the class being declared.
The superclass relationship is the transitive closure of the direct superclass relationship. A class A is a superclass of class C if either of the following is true:
A is the direct superclass of C.
Where a class B is the direct superclass of C, A is a superclass of B, applying this definition recursively.
A class is said to be a direct subclass of its direct superclass, and a subclass of each of its superclasses.
Example 8.1.4-1. Direct Superclasses and Subclasses
class Point { int x, y; }
final class ColoredPoint extends Point { int color; }
class Colored3DPoint extends ColoredPoint { int z; } // error
Here, the relationships are as follows:
The class Point is a direct subclass of Object.
The class Object is the direct superclass of the class Point.
The class ColoredPoint is a direct subclass of class Point.
The class Point is the direct superclass of class ColoredPoint.
The declaration of class Colored3dPoint causes a compile-time error because it attempts to extend the final class ColoredPoint.
Example 8.1.4-2. Superclasses and Subclasses
class Point { int x, y; }
class ColoredPoint extends Point { int color; }
final class Colored3dPoint extends ColoredPoint { int z; }
Here, the relationships are as follows:
The class Point is a superclass of class ColoredPoint.
The class Point is a superclass of class Colored3dPoint.
The class ColoredPoint is a subclass of class Point.
The class ColoredPoint is a superclass of class Colored3dPoint.
The class Colored3dPoint is a subclass of class ColoredPoint.
The class Colored3dPoint is a subclass of class Point.
A class C directly depends on a class or interface A if A is mentioned in the extends or implements clause of C either as a superclass or superinterface, or as a qualifier in the fully qualified form of a superclass or superinterface name.
A class C depends on a class or interface A if any of the following is true:
C directly depends on A.
C directly depends on an interface I that depends (§9.1.3) on A.
C directly depends on a class B that depends on A, applying this definition recursively.
It is a compile-time error if a class depends on itself.
If circularly declared classes are detected at run time, as classes are loaded, then a ClassCircularityError is thrown (§12.2.1).
Example 8.1.4-3. Class Depends on Itself
class Point extends ColoredPoint { int x, y; }
class ColoredPoint extends Point { int color; }
This program causes a compile-time error because class Point depends on itself.
8.1.5. Superinterfaces
The optional implements clause in a class declaration specifies the direct superinterface types of the class being declared.
ClassImplements:
implements InterfaceTypeList
InterfaceTypeList:
InterfaceType {, InterfaceType}
Each InterfaceType must name an accessible interface (§6.6), or a compile-time error occurs.
It is a compile-time error if any InterfaceType names a interface that is sealed (§9.1.1.4) and the class being declared is not a permitted direct subclass of the named interface (§9.1.4).
If an InterfaceType has type arguments, it must denote a well-formed parameterized type (§4.5), and none of the type arguments may be wildcard type arguments, or a compile-time error occurs.
It is a compile-time error if the same interface is named by a direct superinterface type more than once in a single implements clause. This is true even if the interface is named in different ways.
Example 8.1.5-1. Illegal Superinterfaces
class Redundant implements java.lang.Cloneable, Cloneable {
int x;
}
This program results in a compile-time error because the names java.lang.Cloneable and Cloneable refer to the same interface.
A class whose declaration lacks an implements clause has no direct superinterface types, with one exception: an anonymous class may have a superinterface type (§15.9.5).
An interface is a direct superinterface of a class if the interface is named by one of the direct superinterface types of the class.
An interface I is a superinterface of class C if any of the following is true:
I is a direct superinterface of C.
C has some direct superinterface J for which I is a superinterface, using the definition of "superinterface of an interface" given in §9.1.3.
I is a superinterface of the direct superclass of C.
A class can have a superinterface in more than one way.
A class is said to directly implement its direct superinterfaces, and to implement all of its superinterfaces.
A class is said to be a direct subclass of its direct superinterfaces, and a subclass of all of its superinterfaces.
A class may not declare a direct superclass type and a direct superinterface type, or two direct superinterface types, which are, or which have supertypes (§4.10.2) which are, different parameterizations of the same generic interface (§9.1.2), or a parameterization of a generic interface and a raw type naming that same generic interface. In the case of such a conflict, a compile-time error occurs.
This requirement was introduced in order to support translation by type erasure (§4.6).
Example 8.1.5-2. Superinterfaces
interface Colorable {
void setColor(int color);
int getColor();
}
enum Finish { MATTE, GLOSSY }
interface Paintable extends Colorable {
void setFinish(Finish finish);
Finish getFinish();
}
class Point { int x, y; }
class ColoredPoint extends Point implements Colorable {
int color;
public void setColor(int color) { this.color = color; }
public int getColor() { return color; }
}
class PaintedPoint extends ColoredPoint implements Paintable {
Finish finish;
public void setFinish(Finish finish) {
this.finish = finish;
}
public Finish getFinish() { return finish; }
}
Here, the relationships are as follows:
The interface Paintable is a superinterface of class PaintedPoint.
The interface Colorable is a superinterface of class ColoredPoint and of class PaintedPoint.
The interface Paintable is a subinterface of the interface Colorable, and Colorable is a superinterface of Paintable, as defined in §9.1.3.
The class PaintedPoint has Colorable as a superinterface both because it is a superinterface of ColoredPoint and because it is a superinterface of Paintable.
Example 8.1.5-3. Illegal Multiple Inheritance of an Interface
interface I<T> {}
class B implements I<Integer> {}
class C extends B implements I<String> {}
Class C causes a compile-time error because it attempts to be a subtype of both I<Integer> and I<String>.
Unless the class being declared is abstract, all the abstract member methods of each direct superinterface must be implemented (§8.4.8.1) either by a declaration in this class or by an existing method declaration inherited from the direct superclass or a direct superinterface, because a class that is not abstract is not permitted to have abstract methods (§8.1.1.1).
Each default method (§9.4.3) of a superinterface of the class may optionally be overridden by a method in the class; if not, the default method is typically inherited and its behavior is as specified by its default body.
It is permitted for a single method declaration in a class to implement methods of more than one superinterface.
Example 8.1.5-4. Implementing Methods of a Superinterface
interface Colorable {
void setColor(int color);
int getColor();
}
class Point { int x, y; };
class ColoredPoint extends Point implements Colorable {
int color;
}
This program causes a compile-time error, because ColoredPoint is not an abstract class but fails to provide an implementation of methods setColor and getColor of the interface Colorable.
In the following program:
interface Fish { int getNumberOfScales(); }
interface Piano { int getNumberOfScales(); }
class Tuna implements Fish, Piano {
// You can tune a piano, but can you tuna fish?
public int getNumberOfScales() { return 91; }
}
the method getNumberOfScales in class Tuna has a name, signature, and return type that matches the method declared in interface Fish and also matches the method declared in interface Piano; it is considered to implement both.
On the other hand, in a situation such as this:
interface Fish { int getNumberOfScales(); }
interface StringBass { double getNumberOfScales(); }
class Bass implements Fish, StringBass {
// This declaration cannot be correct,
// no matter what type is used.
public ?? getNumberOfScales() { return 91; }
}
it is impossible to declare a method named getNumberOfScales whose signature and return type are compatible with those of both the methods declared in interface Fish and in interface StringBass, because a class cannot have multiple methods with the same signature and different primitive return types (§8.4). Therefore, it is impossible for a single class to implement both interface Fish and interface StringBass (§8.4.8).
8.1.6. Permitted Direct Subclasses
The optional permits clause in a normal class declaration specifies all the classes intended as direct subclasses of the class being declared (§8.1.1.2).
ClassPermits:
permits TypeName {, TypeName}
It is a compile-time error if a class declaration has a permits clause but no sealed modifier.
Every TypeName must name an accessible class (§6.6), or a compile-time error occurs.
It is a compile-time error if the same class is specified more than once in a permits clause. This is true even if the class is named in different ways.
The canonical name of a class does not need to be used in a permits clause, but a permits clause can only specify a class once. For example, the following program fails to compile:
package p;
sealed class A permits B, C, p.B {} // error
non-sealed class B extends A {}
non-sealed class C extends A {}
If a sealed class C is associated with a named module (§7.3), then every class specified in the permits clause of C's declaration must be associated with the same module as C, or a compile-time error occurs.
If a sealed class C is associated with an unnamed module (§7.7.5), then every class specified in the permits clause of C's declaration must belong to the same package as C, or a compile-time error occurs.
A sealed class and its direct subclasses need to refer to each other in a circular fashion, in permits and extends clauses, respectively. Therefore, in a modular codebase, they must be co-located in the same module, as classes in different modules cannot refer to each other in a circular fashion. Co-location is desirable in any case because a sealed class hierarchy should always be declared within a single maintenance domain, where the same developer or group of developers is responsible for maintaining the hierarchy. A named module typically represents a maintenance domain in a modular codebase.
If the declaration of a sealed class C has a permits clause, then the permitted direct subclasses of C are the classes specified by the permits clause.
Every permitted direct subclass specified by the permits clause must be a direct subclass of C (§8.1.4), or a compile-time error occurs.
If the declaration of a sealed class C lacks a permits clause, then the permitted direct subclasses of C are as follows:
If C is not an enum class, then its permitted direct subclasses are those classes declared in the same compilation unit as C (§7.3) which have a canonical name (§6.7) and whose direct superclass is C.
That is, the permitted direct subclasses are inferred as the classes in the same compilation unit that specify C as their direct superclass. The requirement for a canonical name means that no local classes or anonymous classes will be considered.
It is a compile-time error if the declaration of a sealed class C lacks a permits clause and C has no permitted direct subclasses.
If C is an enum class, then its permitted direct subclasses, if any, are specified in §8.9.
8.1.7. Class Body and Member Declarations
A class body may contain declarations of members of the class, that is, fields (§8.3), methods (§8.4), classes, and interfaces (§8.5).
A class body may also contain instance initializers (§8.6), static initializers (§8.7), and declarations of constructors (§8.8) for the class.
ClassBody:
{ {ClassBodyDeclaration} }
ClassBodyDeclaration:
ClassMemberDeclaration
InstanceInitializer
StaticInitializer
ConstructorDeclaration
ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration
ClassDeclaration
InterfaceDeclaration
;
The scope and shadowing of a declaration of a member m declared in or inherited by a class C is specified in §6.3 and §6.4.1.
If C is a nested class, there may be definitions of the same kind (variable, method, or type) and name as m in enclosing scopes. (The scopes may be blocks, classes, or packages.) In all such cases, the member m declared in or inherited by C shadows the other definitions of the same kind and name.
8.2. Class Members
The members of a class are all of the following:
Members inherited from its direct superclass type (§8.1.4), except in the class Object, which has no direct superclass type
Members inherited from any direct superinterface types (§8.1.5)
Members declared in the body of the class (§8.1.7)
Members of a class that are declared private are not inherited by subclasses of that class.
Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.
Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
We use the phrase the type of a member to denote:
For a field, its type.
For a method, an ordered 4-tuple (known as a method type) consisting of:
type parameters: the declarations of any type parameters of the method member (§8.4.4).
parameter types: a list of the types of the formal parameters of the method member (§8.4.1).
return type: the return type of the method member (§8.4.5).
throws clause: exception types declared in the throws clause of the method member (§8.4.6).
Fields, methods, member classes, and member interfaces of a class may have the same name, since they are used in different contexts and are disambiguated by different lookup procedures (§6.5). However, this is discouraged as a matter of style.
Example 8.2-1. Use of Class Members
class Point {
int x, y;
private Point() { reset(); }
Point(int x, int y) { this.x = x; this.y = y; }
private void reset() { this.x = 0; this.y = 0; }
}
class ColoredPoint extends Point {
int color;
void clear() { reset(); } // error
}
class Test {
public static void main(String[] args) {
ColoredPoint c = new ColoredPoint(0, 0); // error
c.reset(); // error
}
}
This program causes four compile-time errors.
One error occurs because ColoredPoint has no constructor declared with two int parameters, as requested by the use in main. This illustrates the fact that ColoredPoint does not inherit the constructors of its superclass Point.
Another error occurs because ColoredPoint declares no constructors, and therefore a default constructor for it is implicitly declared (§8.8.9), and this default constructor is equivalent to:
ColoredPoint() { super(); }
which invokes the constructor, with no arguments, for the direct superclass of the class ColoredPoint. The error is that the constructor for Point that takes no arguments is private, and therefore is not accessible outside the class Point, even through a superclass constructor invocation (§8.8.7).
Two more errors occur because the method reset of class Point is private, and therefore is not inherited by class ColoredPoint. The method invocations in method clear of class ColoredPoint and in method main of class Test are therefore not correct.
Example 8.2-2. Inheritance of Class Members with Package Access
Consider the example where the points package declares two compilation units:
package points;
public class Point {
int x, y;
public void move(int dx, int dy) { x += dx; y += dy; }
}
and:
package points;
public class Point3d extends Point {
int z;
public void move(int dx, int dy, int dz) {
x += dx; y += dy; z += dz;
}
}
and a third compilation unit, in another package, is:
import points.Point3d;
class Point4d extends Point3d {
int w;