-
Notifications
You must be signed in to change notification settings - Fork 0
/
chapter-9.txt
1951 lines (1087 loc) · 114 KB
/
chapter-9.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 9. Interfaces
Table of Contents
9.1. Interface Declarations
9.1.1. Interface Modifiers
9.1.1.1. abstract Interfaces
9.1.1.2. strictfp Interfaces
9.1.1.3. static Interfaces
9.1.1.4. sealed and non-sealed Interfaces
9.1.2. Generic Interfaces and Type Parameters
9.1.3. Superinterfaces and Subinterfaces
9.1.4. Permitted Direct Subclasses and Subinterfaces
9.1.5. Interface Body and Member Declarations
9.2. Interface Members
9.3. Field (Constant) Declarations
9.3.1. Initialization of Fields in Interfaces
9.4. Method Declarations
9.4.1. Inheritance and Overriding
9.4.1.1. Overriding (by Instance Methods)
9.4.1.2. Requirements in Overriding
9.4.1.3. Inheriting Methods with Override-Equivalent Signatures
9.4.2. Overloading
9.4.3. Interface Method Body
9.5. Member Class and Interface Declarations
9.6. Annotation Interfaces
9.6.1. Annotation Interface Elements
9.6.2. Defaults for Annotation Interface Elements
9.6.3. Repeatable Annotation Interfaces
9.6.4. Predefined Annotation Interfaces
9.6.4.1. @Target
9.6.4.2. @Retention
9.6.4.3. @Inherited
9.6.4.4. @Override
9.6.4.5. @SuppressWarnings
9.6.4.6. @Deprecated
9.6.4.7. @SafeVarargs
9.6.4.8. @Repeatable
9.6.4.9. @FunctionalInterface
9.7. Annotations
9.7.1. Normal Annotations
9.7.2. Marker Annotations
9.7.3. Single-Element Annotations
9.7.4. Where Annotations May Appear
9.7.5. Multiple Annotations of the Same Interface
9.8. Functional Interfaces
9.9. Function Types
An interface declaration defines a new interface that can be implemented by one or more classes. Programs can use interfaces to provide a common supertype for otherwise unrelated classes, and to make it unnecessary for related classes to share a common abstract superclass.
Interfaces have no instance variables, and typically declare one or more abstract methods; otherwise unrelated classes can implement an interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.
A top level interface (§7.6) is an interface declared directly in a compilation unit.
A nested interface is any interface whose declaration occurs within the body of another class or interface declaration. A nested interface may be a member interface (§8.5, §9.5) or a local interface (§14.3).
An annotation interface (§9.6) is an interface declared with distinct syntax, intended to be implemented by reflective representations of annotations (§9.7).
This chapter discusses the common semantics of all interfaces. Details that are specific to particular kinds of interfaces are discussed in the sections dedicated to these constructs.
An interface may be declared to be a direct extension of one or more other interfaces, meaning that it inherits all the member classes and interfaces, instance methods, and static fields of the interfaces it extends, except for any members that it may override or hide.
A class may be declared to directly implement one or more interfaces (§8.1.5), meaning that any instance of the class implements all the abstract methods specified by the interface or interfaces. A class necessarily implements all the interfaces that its direct superclasses and direct superinterfaces do. This (multiple) interface inheritance allows objects to support (multiple) common behaviors without sharing a superclass.
Unlike a class, an interface cannot be declared final. However, an interface may be declared sealed (§9.1.1.4) to limit its subclasses and subinterfaces.
A variable whose declared type is an interface type may have as its value a reference to any instance of a class which implements the specified interface. It is not sufficient that the class happen to implement all the abstract methods of the interface; the class or one of its superclasses must actually be declared to implement the interface, or else the class is not considered to implement the interface.
9.1. Interface Declarations
An interface declaration specifies an interface.
There are two kinds of interface declarations: normal interface declarations and annotation interface declarations (§9.6).
InterfaceDeclaration:
NormalInterfaceDeclaration
AnnotationInterfaceDeclaration
NormalInterfaceDeclaration:
{InterfaceModifier} interface TypeIdentifier [TypeParameters] [InterfaceExtends] [InterfacePermits] InterfaceBody
The TypeIdentifier in an interface declaration specifies the name of the interface.
It is a compile-time error if an interface has the same simple name as any of its enclosing classes or interfaces.
The scope and shadowing of an interface declaration is specified in §6.3 and §6.4.1.
9.1.1. Interface Modifiers
An interface declaration may include interface modifiers.
InterfaceModifier:
(one of)
Annotation public protected private
abstract static sealed non-sealed strictfp
The rules concerning annotation modifiers for an interface declaration are specified in §9.7.4 and §9.7.5.
The access modifier public (§6.6) pertains only to top level interfaces (§7.6) and member interfaces (§8.5, §9.5), not to local interfaces (§14.3).
The access modifiers protected and private pertain only to member interfaces.
The modifier static pertains only to member interfaces and local interfaces.
It is a compile-time error if the same keyword appears more than once as a modifier for an interface declaration, or if a interface declaration has more than one of the access modifiers public, protected, and private.
It is a compile-time error if an interface declaration has more than one of the modifiers sealed and non-sealed.
If two or more (distinct) interface modifiers appear in an interface declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for InterfaceModifier.
9.1.1.1. abstract Interfaces
Every interface is implicitly abstract.
This modifier is obsolete and should not be used in new code.
9.1.1.2. strictfp Interfaces
The strictfp modifier on an interface declaration is obsolete and should not be used in new code. Its presence or absence has no effect at compile time or run time.
9.1.1.3. static Interfaces
A nested interface is implicitly static. That is, every member interface and local interface is static. It is permitted for the declaration of a member interface to redundantly specify the static modifier (§9.5), but it is not permitted for the declaration of a local interface (§14.3).
Because a nested interface is static, it has no immediately enclosing instance (§8.1.3). References from a nested interface to type parameters, instance variables, local variables, formal parameters, exception parameters, or instance methods in lexically enclosing class, interface, or method declarations are disallowed (§6.5.5.1, §6.5.6.1, §15.12.3).
9.1.1.4. sealed and non-sealed Interfaces
An interface can be declared sealed if all its direct subclasses and direct subinterfaces are known when the interface is declared (§9.1.4), and no other direct subclasses or direct subinterfaces are desired or required.
It is useful to recall that a class is said to be a direct subclass of its direct superinterfaces (§8.1.5).
An interface is freely extensible if none of its direct superinterfaces are sealed (§9.1.3), and it is not sealed itself.
An interface that has a sealed direct superinterface is freely extensible if and only if it is declared non-sealed.
It is a compile-time error if an interface has a sealed direct superinterface and is not declared sealed or non-sealed.
It is a compile-time error if an interface is declared non-sealed but has no sealed direct superinterface.
9.1.2. Generic Interfaces and Type Parameters
An interface is generic if the interface declaration declares one or more type variables (§4.4).
These type variables are known as the type parameters of the interface. The type parameter section follows the interface name and is delimited by angle brackets.
The following productions from §8.1.2 and §4.4 are shown here for convenience:
TypeParameters:
< TypeParameterList >
TypeParameterList:
TypeParameter {, TypeParameter}
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 an interface'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 interface's type parameter section depends on itself.
The scope and shadowing of an interface's type parameter is specified in §6.3 and §6.4.1.
References to an interface's type parameter from a static context or a nested class or interface are restricted, as specified in §6.5.5.1.
A generic interface 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 interface at run time.
9.1.3. Superinterfaces and Subinterfaces
If an extends clause is provided, then the interface being declared extends each of the specified interface types and therefore inherits the member classes, member interfaces, instance methods, and static fields of each of those interface types.
The specified interface types are the direct superinterface types of the interface being declared.
Any class that implements the declared interface is also considered to implement all the interfaces that this interface extends.
InterfaceExtends:
extends InterfaceTypeList
The following production from §8.1.5 is shown here for convenience:
InterfaceTypeList:
InterfaceType {, InterfaceType}
Each InterfaceType in the extends clause of an interface declaration 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 interface being declared is not a permitted direct subinterface 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.
One interface is a direct superinterface of another interface if the first interface is named by one of the direct superinterface types of the second interface.
The superinterface relationship is the transitive closure of the direct superinterface relationship. An interface I is a superinterface of interface K if either of the following is true:
I is a direct superinterface of K.
Where J is a direct superinterface of K, I is a superinterface of J, applying this definition recursively.
An interface is said to be a direct subinterface of its direct superinterface, and a subinterface of each of its superinterfaces.
While every class is an extension of class Object, there is no single interface of which all interfaces are extensions.
An interface I directly depends on a class or interface A if A is mentioned in the extends clause of I either as a superinterface or as a qualifier in the fully qualified form of a superinterface name.
An interface I depends on a class or interface A if any of the following is true:
I directly depends on A.
I directly depends on a class C that depends on A (§8.1.5).
I directly depends on an interface J that depends on A, applying this definition recursively.
It is a compile-time error if an interface depends on itself.
If circularly declared interfaces are detected at run time, as interfaces are loaded, then a ClassCircularityError is thrown (§12.2.1).
9.1.4. Permitted Direct Subclasses and Subinterfaces
The optional permits clause in a normal interface declaration specifies all the classes and interfaces intended as direct subclasses and direct subinterfaces of the interface being declared (§9.1.1.4).
InterfacePermits:
permits TypeName {, TypeName}
It is a compile-time error if an interface declaration has a permits clause but no sealed modifier.
Every TypeName must name an accessible class or interface (§6.6), or a compile-time error occurs.
It is a compile-time error if the same class or interface is specified more than once in a permits clause. This is true even if the class or interface is named in different ways.
The canonical name of a class or interface does not need to be used in a permits clause, but a permits clause can only specify a class or interface once. For example, the following program fails to compile:
package p;
sealed interface I permits C, D, p.C {} // error
non-sealed class C implements I {}
non-sealed class D implements I {}
If a sealed interface I is associated with a named module (§7.3), then every class or interface specified in the permits clause of I's declaration must be associated with the same module as I, or a compile-time error occurs.
If a sealed interface I is associated with an unnamed module (§7.7.5), then every class or interface specified in the permits clause of I's declaration must belong to the same package as I, or a compile-time error occurs.
A sealed interface and its direct subclasses and direct subinterfaces need to refer to each other in a circular fashion, in permits, implements, and extends clauses, respectively. Therefore, in a modular codebase, they must be co-located in the same module, as classes and interfaces in different modules cannot refer to each other in a circular fashion. Co-location is desirable in any case because a sealed interface 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 interface I has a permits clause, then the permitted direct subclasses and subinterfaces of I are the classes and interfaces specified by the permits clause.
Every permitted direct subclass and subinterface specified by the permits clause must be a direct subclass of I (§8.1.5) or a direct subinterface of I (§9.1.3), or a compile-time error occurs.
If the declaration of a sealed interface I lacks a permits clause, then the permitted direct subclasses and subinterfaces of I are those classes and interfaces declared in the same compilation unit as I (§7.3) which have a canonical name (§6.7) and whose direct superinterfaces include I.
That is, the permitted direct subclasses and subinterfaces are inferred as the classes and interfaces in the same compilation unit that specify I as a direct superinterface. The requirement for a canonical name means that no local classes, local interfaces, or anonymous classes will be considered.
It is a compile-time error if the declaration of a sealed interface I lacks a permits clause and I has no permitted direct subclasses or subinterfaces.
9.1.5. Interface Body and Member Declarations
An interface body may contain declarations of members of the interface, that is, fields (§9.3), methods (§9.4), classes, and interfaces (§9.5).
InterfaceBody:
{ {InterfaceMemberDeclaration} }
InterfaceMemberDeclaration:
ConstantDeclaration
InterfaceMethodDeclaration
ClassDeclaration
InterfaceDeclaration
;
The scope of a declaration of a member m declared in or inherited by an interface I is specified in §6.3.
9.2. Interface Members
The members of an interface are:
Members declared in the body of the interface declaration (§9.1.5).
Members inherited from any direct superinterface types (§9.1.3).
If an interface has no direct superinterface types, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object (§4.3.2), unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
It is a compile-time error if the interface explicitly declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but which has a different return type, or an incompatible throws clause, or is not abstract.
The interface inherits, from the interfaces it extends, all members of those interfaces, except for (i) fields, classes, and interfaces that it hides, (ii) abstract methods and default methods that it overrides (§9.4.1), (iii) private methods, and (iv) static methods.
Fields, methods, member classes, and member interfaces of an interface 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.
9.3. Field (Constant) Declarations
ConstantDeclaration:
{ConstantModifier} UnannType VariableDeclaratorList ;
ConstantModifier:
(one of)
Annotation public
static final
See §8.3 for UnannType. The following productions from §4.3 and §8.3 are shown here for convenience:
VariableDeclaratorList:
VariableDeclarator {, VariableDeclarator}
VariableDeclarator:
VariableDeclaratorId [= VariableInitializer]
VariableDeclaratorId:
Identifier [Dims]
_
Dims:
{Annotation} [ ] {{Annotation} [ ]}
VariableInitializer:
Expression
ArrayInitializer
The rules concerning annotation modifiers for an interface field declaration are specified in §9.7.4 and §9.7.5.
Every field declaration in the body of an interface declaration is implicitly public, static, and final. It is permitted to redundantly specify any or all of these modifiers for such fields.
It is a compile-time error if the same keyword appears more than once as a modifier for a field declaration.
If two or more (distinct) field modifiers appear in a field declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for ConstantModifier.
The declared type of a field is denoted by UnannType if no bracket pairs appear in UnannType and VariableDeclaratorId, and is specified by §10.2 otherwise.
Every declaration of an interface field must include an Identifier, or a compile-time error occurs.
The scope and shadowing of an interface field declaration is specified in §6.3 and §6.4.1.
Because an interface field is static, its declaration introduces a static context (§8.1.3), which limits the use of constructs that refer to the current object. Notably, the keywords this and super are prohibited in a static context (§15.8.3, §15.11.2), as are unqualified references to instance variables, instance methods, and type parameters of lexically enclosing declarations (§6.5.5.1, §6.5.6.1, §15.12.3).
It is a compile-time error for the body of an interface declaration to declare two fields with the same name.
If the interface declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superinterfaces of the interface.
It is possible for an interface to inherit more than one field with the same name. Such a situation does not in itself cause a compile-time error. However, any attempt within the body of the interface declaration to refer to any such field by its simple name will result in a compile-time error, because the reference is ambiguous.
There might be several paths by which the same field declaration is inherited from an interface. In such a situation, the field is considered to be inherited only once, and it may be referred to by its simple name without ambiguity.
Example 9.3-1. Ambiguous Inherited Fields
If two fields with the same name are inherited by an interface because, for example, two of its direct superinterfaces declare fields with that name, then a single ambiguous member results. Any use of this ambiguous member will result in a compile-time error. In the program:
interface BaseColors {
int RED = 1, GREEN = 2, BLUE = 4;
}
interface RainbowColors extends BaseColors {
int YELLOW = 3, ORANGE = 5, INDIGO = 6, VIOLET = 7;
}
interface PrintColors extends BaseColors {
int YELLOW = 8, CYAN = 16, MAGENTA = 32;
}
interface LotsOfColors extends RainbowColors, PrintColors {
int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90;
}
the interface LotsOfColors inherits two fields named YELLOW. This is all right as long as the interface does not contain any reference by simple name to the field YELLOW. (Such a reference could occur within a variable initializer for a field.)
Even if interface PrintColors were to give the value 3 to YELLOW rather than the value 8, a reference to field YELLOW within interface LotsOfColors would still be considered ambiguous.
Example 9.3-2. Multiply Inherited Fields
If a single field is inherited multiple times from the same interface because, for example, both this interface and one of this interface's direct superinterfaces extend the interface that declares the field, then only a single member results. This situation does not in itself cause a compile-time error.
In the previous example, the fields RED, GREEN, and BLUE are inherited by interface LotsOfColors in more than one way, through interface RainbowColors and also through interface PrintColors, but the reference to field RED in interface LotsOfColors is not considered ambiguous because only one actual declaration of the field RED is involved.
9.3.1. Initialization of Fields in Interfaces
Every declarator in a field declaration of an interface must have a variable initializer, or a compile-time error occurs.
The initializer need not be a constant expression (§15.29).
It is a compile-time error if the initializer of an interface field uses the simple name of the same field or another field whose declaration occurs to the right of the initializer (§3.5) in the same interface.
The initializer of an interface field may not refer to the current object using the keyword this or the keyword super, as specified in §15.8.3, §15.11.2, and §15.12.3.
At run time, the initializer is evaluated and the field assignment performed exactly once, when the interface is initialized (§12.4.2).
Note that interface fields that are constant variables (§4.12.4) are initialized before other interface fields. This also applies to static fields that are constant variables in classes (§8.3.2). Such fields will never be observed to have their default initial values (§4.12.5), even by devious programs.
Example 9.3.1-1. Forward Reference to a Field
interface Test {
float f = j;
int j = 1;
int k = k + 1;
}
This program causes two compile-time errors, because j is referred to in the initialization of f before j is declared, and because the initialization of k refers to k itself.
9.4. Method Declarations
InterfaceMethodDeclaration:
{InterfaceMethodModifier} MethodHeader MethodBody
InterfaceMethodModifier:
(one of)
Annotation public private
abstract default static strictfp
The following productions from §8.4, §8.4.5, and §8.4.7 are shown here for convenience:
MethodHeader:
Result MethodDeclarator [Throws]
TypeParameters {Annotation} Result MethodDeclarator [Throws]
Result:
UnannType
void
MethodDeclarator:
Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]
MethodBody:
Block
;
The rules concerning annotation modifiers for an interface method declaration are specified in §9.7.4 and §9.7.5.
A method in the body of an interface declaration may be declared public or private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of style, to redundantly specify the public modifier for a method declaration in an interface declaration.
A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden.
An interface can declare static methods, which are invoked without reference to a particular object. static interface methods are distinct from default methods, abstract interface methods, and non-static private interface methods, all of which are instance methods.
The declaration of a static interface method introduces a static context (§8.1.3), which limits the use of constructs that refer to the current object. Notably, the keywords this and super are prohibited in a static context (§15.8.3, §15.11.2), as are unqualified references to instance variables, instance methods, and type parameters of lexically enclosing declarations (§6.5.5.1, §6.5.6.1, §15.12.3).
References to an instance method from a static context or a nested class or interface are restricted (§15.12.3).
The strictfp modifier on an interface method declaration is obsolete and should not be used in new code. Its presence or absence has no effect at run time.
An interface method lacking a private, default, or static modifier is implicitly abstract. Its body is represented by a semicolon, not a block. It is permitted, but discouraged as a matter of style, to redundantly specify the abstract modifier for such a method declaration.
Note that an interface method may not be declared with protected or package access, or with the modifiers final, synchronized, or native.
It is a compile-time error if the same keyword appears more than once as a modifier for an interface method declaration, or if an interface method declaration has more than one of the access modifiers public and private (§6.6).
It is a compile-time error if an interface method declaration has more than one of the keywords abstract, default, or static.
It is a compile-time error if an interface method declaration that contains the keyword private also contains the keyword abstract or default. It is permitted for an interface method declaration to contain both private and static.
It is a compile-time error if an interface method declaration that contains the keyword abstract also contains the keyword strictfp.
It is a compile-time error for the body of an interface declaration to declare, explicitly or implicitly, two methods with override-equivalent signatures (§8.4.2). However, an interface may inherit several abstract methods with such signatures (§9.4.1).
A method declared in an interface may be generic. The rules for type parameters of a generic method in an interface are the same as for a generic method in a class (§8.4.4).
9.4.1. Inheritance and Overriding
An interface I inherits from its direct superinterface types all abstract and default methods m for which all of the following are true:
m is a member of a direct superinterface type of I, J.
No method declared in I has a signature that is a subsignature (§8.4.2) of the signature of m as a member of J.
There exists no method m' that is a member of a direct superinterface of I, J' (m distinct from m', J distinct from J'), such that m' overrides from the interface of J' the declaration of the method m (§9.4.1.1).
Note that methods are overridden on a signature-by-signature basis. If, for example, an interface declares two public methods with the same name (§9.4.2), and a subinterface overrides one of them, the subinterface still inherits the other method.
The third clause above prevents a subinterface from re-inheriting a method that has already been overridden by another of its superinterfaces. For example, in this program:
interface Top {
default String name() { return "unnamed"; }
}
interface Left extends Top {
default String name() { return getClass().getName(); }
}
interface Right extends Top {}
interface Bottom extends Left, Right {}
Right inherits name() from Top, but Bottom inherits name() from Left, not Right. This is because name() from Left overrides the declaration of name() in Top.
An interface does not inherit private or static methods from its superinterfaces.
If an interface I declares a private or static method m, and the signature of m is a subsignature of a public instance method m' in a superinterface type of I, and m' would otherwise be accessible to code in I, then a compile-time error occurs.
In essence, a static method in an interface cannot hide an instance method in a superinterface type. This is similar to the rule in §8.4.8.2 whereby a static method in a class cannot hide an instance method in a superclass type or superinterface type. Note that the rule in §8.4.8.2 speaks of a class that "declares or inherits a static method", whereas the rule above speaks only of an interface that "declares a static method", since an interface cannot inherit a static method. Also note that the rule in §8.4.8.2 allows hiding of both instance and static methods in superclasses/superinterfaces, whereas the rule above considers only public instance methods in superinterface types.
Along the same lines, a private method in an interface cannot override an instance method - whether public or private - in a superinterface type. This is similar to the rules in §8.4.8.1 and §8.4.8.3 whereby a private method in a class cannot override any instance method in a superclass type or superinterface type, because §8.4.8.1 requires the overridden method to be non-private and §8.4.8.3 requires the overriding method to provide at least as much access as the overridden method. In summary, only public methods in interfaces can be overridden, and only by public methods in subinterfaces or in implementing classes.
9.4.1.1. Overriding (by Instance Methods)
An instance method mI declared in or inherited by interface I, overrides from I another instance method mJ declared in interface J, iff all of the following are true:
I is a subinterface of J.
I does not inherit mJ.
The signature of mI is a subsignature (§8.4.2) of the signature of mJ as a member of the supertype of I that names J.
mJ is public.
The presence or absence of the strictfp modifier has absolutely no effect on the rules for overriding methods. For example, it is permitted for a method that is not strictfp to override a strictfp method, and it is permitted for a strictfp method to override a method that is not strictfp.
An overridden default method can be accessed by using a method invocation expression (§15.12) that contains the keyword super qualified by a superinterface name.
9.4.1.2. Requirements in Overriding
The relationship between the return type of an interface method and the return types of any overridden interface methods is specified in §8.4.8.3.
The relationship between the throws clause of an interface method and the throws clauses of any overridden interface methods is specified in §8.4.8.3.
The relationship between the signature of an interface method and the signatures of any overridden interface methods is specified in §8.4.8.3.
The relationship between the accessibility of an interface method and the accessibility of any overridden interface methods is specified in §8.4.8.3.
It is a compile-time error if a default method is override-equivalent (§8.4.2) with a non-private method of the class Object, because any class implementing the interface will inherit its own implementation of the method.
The prohibition against declaring one of the Object methods as a default method may be surprising. There are, after all, cases like java.util.List in which the behavior of toString and equals are precisely defined. The motivation becomes clearer, however, when some broader design decisions are understood:
First, methods inherited from a superclass are allowed to override methods inherited from superinterfaces (§8.4.8.1). So, every implementing class would automatically override an interface's toString default. This is longstanding behavior in the Java programming language. It is not something we wish to change with the design of default methods, because that would conflict with the goal of allowing interfaces to unobtrusively evolve, only providing default behavior when a class doesn't already have it through the class hierarchy.
Second, interfaces do not inherit from Object, but rather implicitly declare many of the same methods as Object (§9.2). So, there is no common ancestor for the toString declared in Object and the toString declared in an interface. At best, if both were candidates for inheritance by a class, they would conflict. Working around this problem would require awkward commingling of the class and interface inheritance trees.
Third, use cases for declaring Object methods in interfaces typically assume a linear interface hierarchy; the feature does not generalize very well to multiple inheritance scenarios.
Fourth, the Object methods are so fundamental that it seems dangerous to allow an arbitrary superinterface to silently add a default method that changes their behavior.
An interface is free, however, to define another method that provides behavior useful for classes that override the Object methods. For example, the java.util.List interface could declare an elementString method that produces the string described by the contract of toString; implementors of toString in classes could then delegate to this method.
9.4.1.3. Inheriting Methods with Override-Equivalent Signatures
It is possible for an interface to inherit several methods with override-equivalent signatures (§8.4.2).
If an interface I inherits a default method whose signature is override-equivalent with another method inherited by I, then a compile-time error occurs. (This is the case whether the other method is abstract or default.)
Otherwise, all the inherited methods are abstract, and the interface is considered to inherit all the methods.
One of the inherited methods must be return-type-substitutable for every other inherited method, or else a compile-time error occurs. (The throws clauses do not cause errors in this case.)
There might be several paths by which the same method declaration is inherited from an interface. This fact causes no difficulty and never, of itself, results in a compile-time error.
Naturally, when two different default methods with matching signatures are inherited by a subinterface, there is a behavioral conflict. We actively detect this conflict and notify the programmer with an error, rather than waiting for the problem to arise when a concrete class is compiled. The error can be avoided by declaring a new method that overrides, and thus prevents the inheritance of, all conflicting methods.
Similarly, when an abstract method and a default method with matching signatures are inherited by a subinterface, we produce an error. In this case, it would be possible to give priority to one or the other - perhaps we would assume that the default method provides a reasonable implementation for the abstract method. But this is risky, since other than the coincidental name and signature, we have no reason to believe that the default method behaves consistently with the abstract method's contract - the default method may not have even existed when the subinterface was originally developed. It is safer in this situation to ask the user to actively assert that the default implementation is appropriate (via an overriding declaration).
In contrast, the longstanding behavior for inherited concrete methods in classes is that they override abstract methods declared in interfaces (see §8.4.8). The same argument about potential contract violation applies here, but in this case there is an inherent imbalance between classes and interfaces. We prefer, in order to preserve the independent nature of class hierarchies, to minimize class-interface clashes by simply giving priority to concrete methods.
9.4.2. Overloading
If two methods of an interface (whether both declared in the same interface, or both inherited by an interface, or one declared and one inherited) have the same name but different signatures that are not override-equivalent (§8.4.2), then the method name is said to be overloaded.
This fact causes no difficulty and never of itself results in a compile-time error. There is no required relationship between the return types or between the throws clauses of two methods with the same name but different signatures that are not override-equivalent.
Example 9.4.2-1. Overloading an abstract Method Declaration
interface PointInterface {
void move(int dx, int dy);
}
interface RealPointInterface extends PointInterface {
void move(float dx, float dy);
void move(double dx, double dy);
}
Here, the method named move is overloaded in interface RealPointInterface with three different signatures, two of them declared and one inherited. Any non-abstract class that implements interface RealPointInterface must provide implementations of all three method signatures.
9.4.3. Interface Method Body
A default method has a block body. This block of code provides an implementation of the method in the event that a class implements the interface but does not provide its own implementation of the method.
A private or static interface method also has a block body, which provides the implementation of the method.
It is a compile-time error if an interface method declaration is abstract (explicitly or implicitly) and has a block for its body.
It is a compile-time error if an interface method declaration is default, private, or static, and has a semicolon for its body.
The rules for return statements in a method body are specified in §14.17.
If a method is declared to have a return type (§8.4.5), then a compile-time error occurs if the body of the method can complete normally (§14.1).
9.5. Member Class and Interface Declarations
An interface body (§9.1.5) may contain declarations of member classes and member interfaces (§8.5).
Every member class or interface declaration in the body of an interface declaration is implicitly public and static (§9.1.1.3). It is permitted to redundantly specify either or both of these modifiers.
It is a compile-time error if a member class or interface declaration in an interface has the modifier protected or private.
The rules for modifiers of a member class declaration in the body of an interface declaration are specified in §8.1.1.
The rules for modifiers of a member interface declaration in the body of an interface declaration are specified in §9.1.1.
If an interface declares a member class or interface with a certain name, then the declaration of the member class or interface is said to hide any and all accessible declarations of member classes and interface with the same name in superinterfaces of the interface.
An interface inherits from its direct superinterfaces all the member classes and interfaces of the direct superinterfaces that are not hidden by a declaration in the interface.
It is possible for an interface to inherit more than one member class or interface with the same name. Such a situation does not in itself cause a compile-time error. However, any attempt within the body of the interface to refer to any such member class or interface by its simple name will result in a compile-time error, because the reference is ambiguous.
There might be several paths by which the same member class or interface declaration is inherited from an interface. In such a situation, the member class or interface is considered to be inherited only once, and it may be referred to by its simple name without ambiguity.
9.6. Annotation Interfaces
An annotation interface declaration specifies an annotation interface, a specialized kind of interface. To distinguish an annotation interface declaration from a normal interface declaration, the keyword interface is preceded by an at sign (@).
AnnotationInterfaceDeclaration:
{InterfaceModifier} @ interface TypeIdentifier AnnotationInterfaceBody
Note that the at sign (@) and the keyword interface are distinct tokens. It is possible to separate them with whitespace, but this is discouraged as a matter of style.
Unless explicitly modified in this section and its subsections, all of the rules that apply to normal interface declarations (§9.1) apply to annotation interface declarations.
For example, annotation interface declarations have the same rules for scope as normal interface declarations.
It is a compile-time error if an annotation interface declaration has the modifier sealed or non-sealed (§9.1.1.4).
An annotation interface declaration may specify a top level interface or a member interface, but not a local interface (§14.3).
An annotation interface declaration is not permitted syntactically to appear within a block, by virtue of the LocalClassOrInterfaceDeclaration production in §14.3.
It is a compile-time error if an annotation interface declaration appears directly or indirectly in the body of a local class, local interface, or anonymous class declaration (§14.3, §15.9.5).
This rule, together with the syntactic restriction on annotation interface declarations noted above, ensures that an annotation interface always has a canonical name (§6.7). Having such a name is important because the purpose of an annotation interface is to be used by annotations in other compilation units. Since a local class or interface does not have a canonical name, an annotation interface declared anywhere within its syntactic body (if that were allowed) would not have a canonical name either.
The following code shows the effect of this rule and the related syntactic restriction:
class C {
@interface A1 {} /* Legal: an annotation interface can be a
member interface */
void m() {
@interface A2 {} /* Illegal: an annotation interface cannot
be a local interface */
class D {
@interface A3 {} /* Illegal: an annotation interface
cannot be specified anywhere within
the body of local class D */
class E {
@interface A4 {}
/* Illegal: an annotation interface cannot be
specified anywhere within the body of local class
D, even as a member of a class E nested in D */
}
}
}
}
An annotation interface is never generic (§9.1.2).
Unlike a normal interface declaration, an annotation interface declaration cannot declare any type variables, by virtue of the AnnotationTypeDeclaration production.
The direct superinterface type of an annotation interface is always java.lang.annotation.Annotation (§9.1.3).
Unlike a normal interface declaration, an annotation interface declaration cannot choose the direct superinterface type via an extends clause, by virtue of the AnnotationTypeDeclaration production.
A consequence of the fact that an annotation interface declaration does not explicitly specify a superinterface type via extends is that a subinterface of an annotation interface is never itself an annotation interface, since the subinterface's declaration necessarily uses an extends clause. Similarly, java.lang.annotation.Annotation is not itself an annotation interface.
An annotation interface inherits several methods from java.lang.annotation.Annotation, including the implicitly declared methods corresponding to the instance methods of Object (§9.2), yet these methods do not define elements of the annotation interface (§9.6.1).
Because these methods do not define elements of the annotation interface, it is illegal to use them in annotations conforming to the annotation interface (§9.7). Without this rule, we could not ensure that elements were of the types representable in annotations, or that accessor methods for them would be available.
9.6.1. Annotation Interface Elements
The body of an annotation interface declaration may contain method declarations, each of which defines an element of the annotation interface. An annotation interface has no elements other than those defined by the methods declared explicitly in the annotation interface declaration.
AnnotationInterfaceBody:
{ {AnnotationInterfaceMemberDeclaration} }
AnnotationInterfaceMemberDeclaration:
AnnotationInterfaceElementDeclaration
ConstantDeclaration
ClassDeclaration
InterfaceDeclaration
;
AnnotationInterfaceElementDeclaration:
{AnnotationInterfaceElementModifier} UnannType Identifier ( ) [Dims] [DefaultValue] ;
AnnotationInterfaceElementModifier:
(one of)
Annotation public
abstract
The following production from §4.3 is shown here for convenience:
Dims:
{Annotation} [ ] {{Annotation} [ ]}
By virtue of the grammar above, a method declaration in an annotation interface declaration cannot have formal parameters, type parameters, or a throws clause; and cannot be private, default, or static. Thus, an annotation interface cannot have the same variety of methods as a normal interface. Note that it is still possible for an annotation interface to inherit a default method from its implicit superinterface, java.lang.annotation.Annotation, though no such default method exists as of Java SE 23.
By convention, the only modifiers that should be present on the declaration of an annotation interface element are annotations.
The return type of a method declared in the body of annotation interface must be one of the following, or a compile-time error occurs:
A primitive type
String
Class or an invocation of Class (§4.5)
An enum class type
An annotation interface type
An array type whose component type is one of the preceding types (§10.1).
This rule precludes elements with nested array types, such as:
@interface Verboten {
String[][] value();
}
The declaration of a method that returns an array is allowed to place the bracket pair that denotes the array type after the empty formal parameter list. This syntax is supported for compatibility with early versions of the Java programming language. It is very strongly recommended that this syntax is not used in new code.
It is a compile-time error if any method declared in an annotation interface has a signature that is override-equivalent (§8.4.2) to that of any public or protected method declared in class Object or in interface java.lang.annotation.Annotation.
It is a compile-time error if the declaration of an annotation interface T contains an element of type T, either directly or indirectly.
For example, this is illegal:
@interface SelfRef { SelfRef value(); }
and so is this:
@interface Ping { Pong value(); }
@interface Pong { Ping value(); }
An annotation interface with no elements is called a marker annotation interface.
An annotation interface with one element is called a single-element annotation interface.
By convention, the name of the sole element in a single-element annotation interface is value. Linguistic support for this convention is provided by single-element annotations (§9.7.3).
Example 9.6.1-1. Annotation Interface Declaration
The following annotation interface declaration defines an annotation interface with several elements:
/**
* Describes the "request-for-enhancement" (RFE)
* that led to the presence of the annotated API element.
*/
@interface RequestForEnhancement {
int id(); // Unique ID number associated with RFE
String synopsis(); // Synopsis of RFE
String engineer(); // Name of engineer who implemented RFE
String date(); // Date RFE was implemented
}
Example 9.6.1-2. Marker Annotation Interface Declaration
The following annotation interface declaration defines a marker annotation interface:
/**
* An annotation with this type indicates that the
* specification of the annotated API element is
* preliminary and subject to change.
*/
@interface Preliminary {}
Example 9.6.1-3. Single-Element Annotation Interface Declarations
The convention that a single-element annotation interface defines an element called value is illustrated in the following annotation interface declaration:
/**
* Associates a copyright notice with the annotated API element.
*/
@interface Copyright {
String value();
}
The following annotation interface declaration defines a single-element annotation interface whose sole element has an array type:
/**
* Associates a list of endorsers with the annotated class.
*/
@interface Endorsers {
String[] value();
}
The following annotation interface declaration shows a Class-typed element whose value is constrained by a bounded wildcard:
interface Formatter {}
// Designates a formatter to pretty-print the annotated class
@interface PrettyPrinter {
Class<? extends Formatter> value();
}
The following annotation interface declaration contains an element whose type is an annotation interface type:
/**
* Indicates the author of the annotated program element.
*/
@interface Author {
Name value();
}
/**
* A person's name. This annotation interface is not
* designed to be used directly to annotate program elements,
* but to define elements of other annotation interfaces.
*/
@interface Name {
String first();
String last();
}
The grammar for annotation interface declarations permits other member declarations besides method declarations. For example, one might choose to declare a nested enum class for use by an element of the annotation interface:
@interface Quality {
enum Level { BAD, INDIFFERENT, GOOD }
Level value();
}
9.6.2. Defaults for Annotation Interface Elements
An annotation interface element may have a default value, specified by attaching the keyword default and a value to the method declaration which defines the element.
DefaultValue:
default ElementValue
The following productions from §9.7.1 are shown here for convenience:
ElementValue:
ConditionalExpression
ElementValueArrayInitializer
Annotation
ElementValueArrayInitializer:
{ [ElementValueList] [,] }
ElementValueList:
ElementValue {, ElementValue}
Note that an annotation interface element which is specified to have a default value is not a default method (§9.4). The declaration of an annotation interface cannot declare default methods (§9.6.1).
It is a compile-time error if the type of the element is not commensurate (§9.7) with the default value specified.
Default values are not compiled into annotations, but rather applied dynamically at the time annotations are read. Thus, changing a default value affects annotations even in classes that were compiled before the change was made (presuming these annotations lack an explicit value for the defaulted element).
Example 9.6.2-1. Annotation Interface Declaration With Default Values
Here is a refinement of the RequestForEnhancement annotation interface from §9.6.1:
@interface RequestForEnhancement {
int id(); // No default - must be specified in
// each annotation
String synopsis(); // No default - must be specified in
// each annotation
String engineer() default "[unassigned]";
String date() default "[unimplemented]";
}
9.6.3. Repeatable Annotation Interfaces
An annotation interface A is repeatable if its declaration is (meta-)annotated with an @Repeatable annotation (§9.6.4.8) whose value element indicates a containing annotation interface of A.
An annotation interface AC is a containing annotation interface of A if all of the following are true:
AC declares a value() method whose return type is A[].
Any methods declared by AC other than value() have a default value.
AC is retained for at least as long as A, where retention is expressed explicitly or implicitly with the @Retention annotation (§9.6.4.2). Specifically:
If the retention of AC is java.lang.annotation.RetentionPolicy.SOURCE, then the retention of A is java.lang.annotation.RetentionPolicy.SOURCE.
If the retention of AC is java.lang.annotation.RetentionPolicy.CLASS, then the retention of A is either java.lang.annotation.RetentionPolicy.CLASS or java.lang.annotation.RetentionPolicy.SOURCE.
If the retention of AC is java.lang.annotation.RetentionPolicy.RUNTIME, then the retention of A is java.lang.annotation.RetentionPolicy.SOURCE, java.lang.annotation.RetentionPolicy.CLASS, or java.lang.annotation.RetentionPolicy.RUNTIME.
A is applicable to at least the same kinds of program element as AC (§9.6.4.1). Specifically, if the kinds of program element where A is applicable are denoted by the set m1, and the kinds of program element where AC is applicable are denoted by the set m2, then each kind in m2 must occur in m1, except that:
If the kind in m2 is java.lang.annotation.ElementType.ANNOTATION_TYPE, then at least one of java.lang.annotation.ElementType.ANNOTATION_TYPE or java.lang.annotation.ElementType.TYPE or java.lang.annotation.ElementType.TYPE_USE must occur in m1.
If the kind in m2 is java.lang.annotation.ElementType.TYPE, then at least one of java.lang.annotation.ElementType.TYPE or java.lang.annotation.ElementType.TYPE_USE must occur in m1.
If the kind in m2 is java.lang.annotation.ElementType.TYPE_PARAMETER, then at least one of java.lang.annotation.ElementType.TYPE_PARAMETER or java.lang.annotation.ElementType.TYPE_USE must occur in m1.
This clause implements the policy that an annotation interface may be repeatable on only some of the kinds of program element where it is applicable.
If the declaration of A has a (meta-)annotation that corresponds to java.lang.annotation.Documented, then the declaration of AC must have a (meta-)annotation that corresponds to java.lang.annotation.Documented.
Note that it is permissible for AC to be @Documented while A is not @Documented.
If the declaration of A has a (meta-)annotation that corresponds to java.lang.annotation.Inherited, then the declaration of AC must have a (meta)-annotation that corresponds to java.lang.annotation.Inherited.
Note that it is permissible for AC to be @Inherited while A is not @Inherited.
It is a compile-time error if an annotation interface A is (meta-)annotated with an @Repeatable annotation whose value element indicates a type which is not a containing annotation interface of A.
Example 9.6.3-1. Ill-formed Containing Annotation Interface
Consider the following declarations:
import java.lang.annotation.Repeatable;
@Repeatable(FooContainer.class)
@interface Foo {}
@interface FooContainer { Object[] value(); }
Compiling the Foo declaration produces a compile-time error because Foo uses @Repeatable to attempt to specify FooContainer as its containing annotation interface, but FooContainer is not in fact a containing annotation interface of Foo. (The return type of FooContainer.value() is not Foo[].)
The @Repeatable annotation cannot be repeated, so only one containing annotation interface can be specified by a repeatable annotation interface.
Allowing more than one containing annotation interface to be specified would cause an undesirable choice at compile time, when multiple annotations of the repeatable annotation interface are logically replaced with a container annotation (§9.7.5).
An annotation interface can be the containing annotation interface of at most one annotation interface.
This is implied by the requirement that if the declaration of an annotation interface A specifies a containing annotation interface of AC, then the value() method of AC has a return type involving A, specifically A[].
An annotation interface cannot specify itself as its containing annotation interface.
This is implied by the requirement on the value() method of the containing annotation interface. Specifically, if an annotation interface A specified itself (via @Repeatable) as its containing annotation interface, then the return type of A's value() method would have to be A[]; but this would cause a compile-time error since an annotation interface cannot refer to itself in its elements (§9.6.1). More generally, two annotation interfaces cannot specify each other as their containing annotation interface, because cyclic annotation interface declarations are illegal.
An annotation interface AC may be the containing annotation interface of some annotation interface A while also having its own containing annotation interface SC. That is, a containing annotation interface may itself be a repeatable annotation interface.
Example 9.6.3-2. Restricting Where Annotations May Repeat
An annotation whose interface declaration indicates a target of java.lang.annotation.ElementType.TYPE can appear in at least as many locations as an annotation whose interface declaration indicates a target of java.lang.annotation.ElementType.ANNOTATION_TYPE. For example, given the following declarations of repeatable and containing annotation interfaces:
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Repeatable(FooContainer.class)
@interface Foo {}
@Target(ElementType.ANNOTATION_TYPE)
@interface FooContainer {
Foo[] value();
}
@Foo can appear on any class or interface declaration while @FooContainer can appear on only annotation interface declarations. Therefore, the following annotation interface declaration is legal:
@Foo @Foo
@interface Anno {}
while the following interface declaration is illegal:
@Foo @Foo
interface Intf {}
More broadly, if Foo is a repeatable annotation interface and FooContainer is its containing annotation interface, then:
If Foo has no @Target meta-annotation and FooContainer has no @Target meta-annotation, then @Foo may be repeated on any program element which supports annotations.
If Foo has no @Target meta-annotation but FooContainer has an @Target meta-annotation, then @Foo may only be repeated on program elements where @FooContainer may appear.
If Foo has an @Target meta-annotation, then in the judgment of the designers of the Java programming language, FooContainer must be declared with knowledge of the Foo's applicability. Specifically, the kinds of program element where FooContainer may appear must logically be the same as, or a subset of, Foo's kinds.
For example, if Foo is applicable to field and method declarations, then FooContainer may legitimately serve as Foo's containing annotation interface if FooContainer is applicable to just field declarations (preventing @Foo from being repeated on method declarations). But if FooContainer is applicable only to formal parameter declarations, then FooContainer was a poor choice of containing annotation interface by Foo because @FooContainer cannot be implicitly declared on some program elements where @Foo is repeated.
Similarly, if Foo is applicable to field and method declarations, then FooContainer cannot legitimately serve as Foo's containing annotation interface if FooContainer is applicable to field and parameter declarations. While it would be possible to take the intersection of the program elements and make Foo repeatable on field declarations only, the presence of additional program elements for FooContainer indicates that FooContainer was not designed as a containing annotation interface for Foo. It would therefore be dangerous for Foo to rely on it.
Example 9.6.3-3. A Repeatable Containing Annotation Interface
The following declarations are legal:
import java.lang.annotation.Repeatable;
// Foo: Repeatable annotation interface
@Repeatable(FooContainer.class)
@interface Foo { int value(); }
// FooContainer: Containing annotation interface of Foo
// Also a repeatable annotation interface itself
@Repeatable(FooContainerContainer.class)
@interface FooContainer { Foo[] value(); }
// FooContainerContainer: Containing annotation interface
// of FooContainer
@interface FooContainerContainer { FooContainer[] value(); }