Navigation: Overview - Part A - Part B - Part C - Part D - Part E - Part F - Part G - Part H - Part J
Sections: 9 - 9.1.1.2 - 9.1.4 - 9.2 - 9.4 - 9.4.1 - 9.4.3 - 9.6.1 - 8.1.1.1 - 8.1.3 - 8.1.5 - 8.4.8 - 8.4.8.1 - 8.4.8.4 - 8.8.7.1 - 15.8 - 15.8.3 - 15.8.4 - 15.11.2 - 15.12 - 15.12.1 - 15.12.2.5 - 15.12.3 - 15.12.4.1 - 6 - 6.6.1 - 7.6
Version 0.6.2. Copyright © 2012 Oracle America, Inc. Legal Notice.
A default method is a method that is declared in an interface with the modifier default
. Its body provides a default implementation for any class that implements the interface without overriding the method. This allows new functionality to be added to existing (and perhaps already widely-distributed) interfaces. More generally, it provides a mechanism for multiple inheritance of behavior.
An interface may also declare static
methods, which work in much the same way as static
methods in classes, except that they are not inherited. Often, an interface is the most appropriate place to declare methods that produce or manipulate objects of the interface type.
An interface method that is neither default
nor static
is implicitly abstract
.
An interface I inherits from its direct superinterfaces all abstract
and default methods that are members of a superinterface, not overridden by a declaration in I, and not already overridden by another method in a superinterface of I.
Similarly, a class C inherits from its direct superclass and direct superinterfaces all abstract
and default methods that are members of a supertype, not overridden by a declaration in C nor a concrete method inherited from the superclass of C, and not already overridden by another method in a supertype of C.
Notably, this implies that a method inherited from a superclass of C can override a default or abstract
method in a superinterface of C. We say the class method overrides the interface method from C. In contrast, an inherited interface method never overrides any methods other than those already overridden at its declaration site.
It is a compile-time error if I or C inherits a default method whose signature is override-equivalent with another method inherited by I. This is the case whether the other method is abstract
or not.
An overridden default method can be accessed by using a method invocation expression of the form InterfaceName.super.m()
. The named interface must be a direct superinterface of the type declaration immediately enclosing the expression.
A this
expression may appear in a default method body; its type is the type of the enclosing interface. Similarly, an anonymous or local class may be declared in a default method body, so the enclosing instance of an inner class may have an interface type.
To avoid confusion with the default
modifier, the access level given implicitly to unmodified declarations in classes is now referred to as package access rather than default access.
Compare JLS 9
An interface declaration introduces a new reference type whose members are classes, interfaces, constants, and abstract methods. This type has no implementation instance variables, and typically declares one or more abstract
methods; otherwise unrelated classes can implement the interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.
...
An interface may be declared to be a direct extension of one or more other interfaces, meaning that it implicitly specifies inherits all the member types, abstract instance methods, and constants 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, 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 any implementation a superclass.
...
strictfp
Interfaces [Modified] Compare JLS 9.1.1.2
The effect of the strictfp
modifier is to make all float
or double
expressions within the interface declaration be explicitly FP-strict (15.4). [jls-9.1.1.2-100]
This implies that all methods declared in the interface, and all nested types declared in the interface, are implicitly strictfp
. [jls-9.1.1.2-110]
The previous sentence mimics 8.1.1.3.
Compare JLS 9.1.4
...
InterfaceMemberDeclaration: ConstantDeclarationAbstractMethodDeclarationInterfaceMethodDeclaration ClassDeclaration InterfaceDeclaration ';'
...
Compare JLS 9.2
The members of an interface are: [jls-9.2-100]
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
, unless an abstract
method with the same signature, same return type, and a compatible throws
clause is explicitly declared by the interface. [jls-9.2-100-C]
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
. [jls-9.2-100-C.1]
It follows that it is a compile-time error if the interface declares a method with a signature that is override-equivalent (8.4.2) to a public
method of Object
, but has a different return type, or has an incompatible throws
clause, or is not abstract
. [jls-9.2-100-C.2]
The interface inherits, from the interfaces it extends, all members of those interfaces, except for fields, classes, and interfaces that it hides, and abstract
or default methods that it overrides, and static
methods. [jls-9.2-110]
Fields, methods, and member types of an interface type 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.
Compare JLS 9.4
InterfaceMethodDeclaration: InterfaceMethodModifiersopt TypeParametersopt Result MethodDeclarator Throwsopt MethodBody InterfaceMethodModifiers: InterfaceMethodModifier InterfaceMethodModifiers InterfaceMethodModifier InterfaceMethodModifier: one of Annotation 'public' 'abstract' 'default' 'static' 'strictfp'
The following is repeated from 8.4.7 to make the presentation here clearer:
MethodBody: Block ';'
If an annotation a (9.7) on a method declaration corresponds to an annotation type T (9.6) and T has a (meta-)annotation m that corresponds to java.lang.annotation.Target
, then m must have an element whose value is java.lang.annotation.ElementType.METHOD
, or a compile-time error occurs. [jls-9.4-110]
Every method declaration in the body of an interface is implicitly public
(6.6). [jls-9.4-120]
It is permitted, but discouraged as a matter of style, to redundantly specify the public
and/or modifier for a method declared in an interface.
abstract
A default method is a method that is declared in an interface with the default
modifier; its body is always represented by a block. It provides a default implementation for any class that implements the interface without overriding the method. [jsr335-9.4-125]
An interface can declare static
methods, which are invoked without reference to a particular object. [jsr335-9.4-127]
It is a compile-time error to use the name of a type parameter of any surrounding declaration in the header or body of a static
method. [jsr335-9.4-128]
The previous sentence mimics 8.4.3.2.
An interface method lacking a default
modifier or a static
modifier is implicitly abstract
, so its body is always represented by a semicolon, not a block. The declaration may optionally include the abstract
keyword. [jls-9.4-130]
The effect of the strictfp
modifier is to make all float
or double
expressions within the method body be explicitly FP-strict (15.4). [jsr335-9.4-135]
The previous sentence mimics 8.4.3.5.
It is a compile-time error if the same modifier appears more than once on a method declared in an interface. [jls-9.4-200]
It is a compile-time error if a method is declared with more than one of the modifiers abstract
, default
, or static
. [jsr335-9.4-202]
It is a compile-time error if an abstract method declaration contains the keyword strictfp
. [jsr335-9.4-205]
It is a compile-time error if a method declared in an interface is declared native
, synchronized
, or final
because . [jls-9.4-210]
static
methods cannot be abstract
It is a compile-time error if a method declared in an interface is
strictfp
or native
or synchronized
because those keywords describe implementation properties rather than interface properties. [jls-9.4-220]
However, a method declared in an interface may be implemented by a method that is declared
strictfp
or native
or synchronized
in a class that implements the interface.
It is a compile-time error if a method declared in an interface is declared
final
. [jls-9.4-240]
However, a method declared in an interface may be implemented by a method that is declared
final
in a class that implements the interface.
It is a compile-time error for the body of an interface to declare, explicitly or implicitly, two methods with override-equivalent signatures (8.4.2). [jls-9.4-260]
However, an interface may inherit several abstract methods with such signatures (9.4.1).
A method 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. [jls-9.4-300]
Compare JLS 9.4.1
An interface I inherits from its direct superinterfaces all abstract
and default methods m for which all of the following are true: [jls-9.4.1-100]
An interface does not inherit static
methods from its superinterfaces.
An instance method m1, declared or inherited by an interface I, overrides from I another instance method, m2, declared in interface J, iff both of the following are true: [jls-9.4.1.1-100]
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.
The previous sentence mimics 8.4.8.1.
It is a compile-time error if an interface declares a static
method whose signature is a subsignature of an instance method inherited from a superinterface. [jsr335-9.4.1-10]
If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type-substitutable (8.4.5) for d2, or a compile-time error occurs. [jls-9.4.1.2-100]
Furthermore, if R1 is not a subtype of R2, a compile-time unchecked warning occurs. [jls-9.4.1.2-110]
Moreover, a method declaration must not have a throws
clause that conflicts (8.4.6) with that of any method that it overrides; otherwise, a compile-time error occurs. [jls-9.4.1.2-200]
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 FP-strict to override an FP-strict method and it is permitted for an FP-strict method to override a method that is not FP-strict.
The previous paragraph mimics 8.4.8.1.
...
An interface inherits from its direct superinterfaces all methods of the superinterfaces that are not overridden by a declaration in the interface.
It is possible for an interface to inherit several methods with override-equivalent signatures (8.4.2).
It is a compile-time error if an interface I inherits a default method whose signature is override-equivalent with another method inherited by I. This is the case whether the other method is abstract
or default
. [jsr335-9.4.1-50]
Otherwise, all the inherited methods are abstract
, and the interface is considered to inherit all the methods. [jls-9.4.1.3-100]
However, one of the inherited methods must be return-type-substitutable for every other inherited method; otherwise, a compile-time error occurs. (The throws
clauses do not cause errors in this case.) [jls-9.4.1.3-110]
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.
The example stating that "methods declared in interfaces are abstract
and thus contain no implementation" should be removed and replaced to include examples of default methods overriding abstract methods and vice versa.
Discussion and motivation:
The third clause in the inheritance definition prevents a subinterface from re-inheriting a method that has already been overridden by another of its superinterfaces.
interface I { default String name() { return "unnamed"; } } interface J extends I { default String name() { return getClass().getName(); } } interface K extends I {} interface Child extends J, K {}The interface
Child
above inheritsJ.name
fromJ
but notI.name
fromK
, becauseI.name
has already been overridden byJ
.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 developer with an error, rather than waiting for the problem to arise when a concrete class is compiled.
Similarly, when an abstract and a default method with matching signatures are inherited, 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, too. 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.
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 static 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. [jsr335-9.4.3-10]
It is a compile-time error if an interface method declaration is default
or static
and has a semicolon for its body. [jsr335-9.4.3-12]
The above mimic 8.4.7.
It is a compile-time error if a default method is override-equivalent with a non-private
method of the class Object
, because any class implementing the interface will inherit its own implementation of the method. [jsr335-9.4.3-20]
It is a compile-time error for the body of a static
method to attempt to reference the current object using the keyword this
or the keyword super
. [jsr335-9.4.3-22]
If a method is declared void
, then its body must not contain any return
statement (14.17) that has an Expression, or a compile-time error occurs. [jsr335-9.4.3-30]
If a method is declared to have a return type, then every return
statement (14.17) in its body must have an Expression, or a compile-time error occurs. [jsr335-9.4.3-40]
If a method is declared to have a return type, then a compile-time error occurs if the body of the method can complete normally (14.1). [jsr335-9.4.3-50]
The previous three sentences mimic 8.4.7.
Discussion and motivation:
The prohibition against declaring one of theObject
methods as a default method may be surprising. There are, after all, cases likejava.util.List
in which the behavior oftoString
andequals
are precisely defined. The motivation becomes clearer, however, when some broader design decisions are well-understood:
- First, methods inherited from a superclass are allowed to override methods inherited from superinterfaces. So every implementing class would automatically override an interface's
toString
default. This is Java's longstanding behavior, and it's 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 the class, through its normal hierarchy, doesn't already have it.- Second, interfaces do not inherit from
Object
, even though they implicitly declare many of the same methods (9.2). So there is no common ancestor fortoString
declared inObject
andtoString
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.The interface is free, however, to define another method that provides behavior useful for classes that override the
Object
methods. For example, thejava.util.List
interface could declare aelementString
method that produces the string described by the contract oftoString
; implementors could then simply delegate to this method.
Compare JLS 9.6.1
...
AnnotationTypeElementDeclaration:AbstractMethodModifiersoptInterfaceMethodModifiersopt Type Identifier '(' ')' Dimsopt DefaultValueopt ';' ...
...
abstract
Classes [Modified] Compare JLS 8.1.1.1
An abstract
class is a class that is incomplete, or to be considered incomplete.
Normal classes may have abstract
methods (8.4.3.1, 9.4), that is, methods that are declared but not yet implemented, only if they are abstract
classes. [jls-8.1.1.1-110]
If a normal class that is not abstract
contains an abstract
method, then a compile-time error occurs. [jls-8.1.1.1-120]
...
A class C has abstract
methods if any either of the following is true: [jls-8.1.1.1-200]
abstract
. [jsr335-8.1.1.1-200-A]
abstract
method declared with package access, and there exists no method that overrides the abstract
method from C or from a superclass of C. [jsr335-8.1.1.1-200-B]
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). [jls-8.1.1.1-300]
...
Discussion and motivation:
These changes are not meant to substantively change the definition of an abstract class, but rather to clarify the existing meaning.
Compare JLS 8.1.3
...
An inner class C is a direct inner class of a class or interface O if O is the immediately lexically enclosing class type declaration of C and the declaration of C does not occur in a static context. [jls-8.1.3-300]
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. [jls-8.1.3-310]
A class or interface O is the zeroth lexically enclosing class type declaration of itself. [jls-8.1.3-320]
A class O is the n'th lexically enclosing class type declaration of a class C if it is the immediately enclosing class type declaration of the n-1'th lexically enclosing class type declaration of C. [jls-8.1.3-330]
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). [jls-8.1.3-400]
...
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. [jls-8.1.3-440]
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, the variable of the corresponding lexically enclosing instance is used. [jls-8.1.3-500]
...
Similar changes to the lexically enclosing class terminology should be made in 8.8.7.1, 13.1, 15.9.2.
Discussion and motivation:
An anonymous or local class may be declared in a default method body; thus, the enclosing instance of an inner class may have an interface type.
Compare JLS 8.1.5
...
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). [jls-8.1.5-500]
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. [jls-8.1.5-510]
...
Compare JLS 8.4.8
A class C inherits from its direct superclass and direct superinterfaces all concrete (both static
and instance) methods m of the superclass abstract
and non-abstract
and superinterfaces for which all of the following are true: [jls-8.4.8-100]
public
, protected
, or declared with A class does not inherit static
methods from its superinterfaces.
A class C inherits from its direct superclass and direct superinterfaces all abstract
and default methods m for which all of the following are true: [jsr335-8.4.8-20]
public
, protected
, or declared with If the method not inherited is declared in a class, or the method not inherited is declared in an interface and the new declaration is
abstract
, then the new declaration is said to override it. [jls-8.4.8-200]
If the method not inherited is
abstract
and the new declaration is not abstract
, then the new declaration is said to implement it. [jls-8.4.8-210]
Discussion and motivation:
This definition of inheritance achieves two goals:
- Clarify that it is possible for an inherited concrete method to prevent the inheritance of an abstract or default method. (Later we will assert that the concrete method overrides the abstract or default method "from C".) This has always been the case (for abstract methods), but it has been poorly specified.
- Introduce, for classes, the rule that one supertype method can prevent the inheritance of another supertype method if the former "already" overrides the latter. This is the same as the rule for interfaces, and prevents conflicts in which multiple default methods are inherited, even though one implementation is clearly meant to supersede the other.
The definitions of "override" and "implement" retracted here are inconsistent with those in the following section. There doesn't seem to be a need to provide a separate definition here.
Compare JLS 8.4.8.1
An instance method m1, declared or inherited by class C, overrides from C another instance method m2, declared in class A, iff all of the following are true: [jls-8.4.8.1-100]
public
. [jls-8.4.8.1-100-C-1]
protected
. [jsr335-8.4.8.1-100-C-3]
An instance method m1, declared or inherited by class C, overrides from C another method m2, declared in an interface I, iff all of the following are true: [jsr335-8.4.8.1-20]
abstract
or default method. [jsr335-8.4.8.1-20-C]
If a non-abstract
method m1 overrides an abstract
method m2 from a class C, then m1 is said to implement m2 from C. [jsr335-8.4.8.1-30]
...
Discussion and motivation:
Previously, the overriding relationship between a class method and an interface method was unspecified. That has been fixed. Most of the other changes here are to extend the notion of overriding to handle methods that override another from some subclass of their declaring class. This can happen in two ways:
- A concrete method in a generic superclass can, under certain parameterizations, have the same signature as an abstract method in that class. In this case, the concrete method is inherited and the abstract method is not (as described above). The inherited method should then be considered to override its abstract peer from C. (This scenario is complicated by package access: if C is in a different package, then m2 would not have been inherited anyway, and should not be considered overridden.)
- An inherited class method can override a superinterface method. (Happily, package access is not a concern here.)
Compare JLS 8.4.8.4
It is possible for a class to inherit multiple methods with override-equivalent signatures (8.4.2).
It is a compile-time error if a class C inherits a concrete method whose signature is a subsignature of override-equivalent with another concrete method inherited by C. This can happen if a superclass is generic, and it has two methods that were distinct in the generic declaration, but have the same signature in the particular invocation used. [jls-8.4.8.4-110]
It is a compile-time error if a class C inherits a default method whose signature is override-equivalent with another method inherited by C, unless there exists an abstract
method declared in a superclass of C and inherited by C that is override-equivalent with the two methods. [jls-8.4.8.4-112]
Note that this exception does not apply if all override-equivalent abstract
methods inherited by C were declared in interfaces.
Otherwise, there are two possible cases:
If one of the inherited methods is not
abstract
, ... [jls-8.4.8.4-120-A]
If all the inherited methods are Otherwise, the set of override-equivalent methods consists of at least one abstract
abstract
method and zero or more default methods; then the class is necessarily an abstract
class and is considered to inherit all the methods. [jls-8.4.8.4-120-B]
abstract
One of the inherited methods must be return-type-substitutable for every other inherited method; otherwise, a compile-time error occurs. (The throws
clauses do not cause errors in this case.) [jls-8.4.8.4-120-B.1]
There might be several paths by which the same method declaration might be is inherited from an interface. This fact causes no difficulty and never, of itself, results in a compile-time error.
Discussion and motivation:
This is a dramatic simplification of this section, because the special rule allowing a concrete inherited method to "override" an abstract inherited method was eliminated in favor of a more accurate definition of inheritance (8.4.8). The special rules for this scenario are no longer necessary, because they are covered by the usual rules for overriding (8.4.8.3).This section is now small enough that it may be preferable to merge it with another section.
An exception to the strict default-abstract and default-default conflict rules is made when anabstract
method is declared in a superclass: this assertion of abstract-ness coming from the superclass hierarchy essentially trumps the default, making the default method act as if it were abstract. However, the abstract class method does not override the default method(s), because interfaces are still allowed to refine the signature of the abstract method coming from the class hierarchy.
Compare JLS 15.8
...
PrimaryNoNewArray: Literal Type '.' 'class' 'void' '.' 'class' 'this'ClassNameTypeName '.' 'this' ...
...
this
[Modified] Compare JLS 15.8.3
The keyword this
may be used only in the body of an instance method, default method, instance initializer, or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs. [jls-15.8.3-100]
When used as a primary expression, the keyword this
denotes a value that is a reference to the object for which the instance or default method was invoked (15.12), or to the object being constructed. [jls-15.8.3-200]
Additional text about lambda expressions was added here in Part B, 15.8.3.
The type of this
is the class or interface type T within which the keyword this
occurs. [jls-15.8.3-210]
At run-time, the class of the actual object referred to may be T, if it is a class type, or a class that is a subtype of T. [jls-15.8.3-220]
...
this
[Modified] Compare JLS 15.8.4
Any lexically enclosing instance (8.1.3) can be referred to by explicitly qualifying the keyword this
.
Let C T be the class type denoted by ClassName TypeName. Let n be an integer such that C T is the n'th lexically enclosing class type declaration of the class or interface in which the qualified this
expression appears. [jls-15.8.4-110]
The value of an expression of the form ClassName TypeName . this
is the n'th lexically enclosing instance of this
. [jls-15.8.4-120]
The type of the expression is C T. [jls-15.8.4-200]
It is a compile-time error if the current class or interface is not an inner class of C T or C T itself. [jls-15.8.4-210]
super
[Modified] Compare JLS 15.11.2
...
The forms using the keyword super
are valid only in an instance method, instance initializer, constructor, or in the initializer of an instance variable of a class. If they appear anywhere else, a compile-time error occurs. [jls-15.11.2-200]
These are exactly the same situations in which the keyword this
may be used in a class declaration (15.8.3).
...
Compare JLS 15.12
A method invocation expression is used to invoke a class or instance method.
MethodInvocation: MethodName '(' ArgumentListopt ')' Primary '.' NonWildTypeArgumentsopt Identifier '(' ArgumentListopt ')' 'super' '.' NonWildTypeArgumentsopt Identifier '(' ArgumentListopt ')'ClassNameTypeName '.' 'super' '.' NonWildTypeArgumentsopt Identifier '(' ArgumentListopt ')' TypeName '.' NonWildTypeArguments Identifier '(' ArgumentListopt ')'
...
Compare JLS 15.12.1
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked and which class or interface to check for definitions of methods of that name. There are several cases to consider, depending on the form that precedes the left parenthesis, as follows. [jls-15.12.1-100]
.
Identifier, then the name of the method is the Identifier and the If TypeName is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only static
methods and interfaces have no static
methods. [jls-15.12.1-100-A-2.1]
.
Identifier. ... [jls-15.12.1-100-A-3].
NonWildTypeArgumentsopt Identifier, ... [jls-15.12.1-100-B]super
.
NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier and the class to be searched is the superclass of the class whose declaration contains the method invocation. [jls-15.12.1-100-C]
Let T be the type declaration immediately enclosing the method invocation. It is a compile-time error if T is the class Object
or T is an interface. [jls-15.12.1-100-C.1]
.
super
.
NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier. [jls-15.12.1-100-D]
If TypeName denotes a class, C, then the class to be searched is the superclass of C. [jls-15.12.1-100-D']
It is a compile-time error if C is not a lexically enclosing class of the current class. [jls-15.12.1-100-D.1]
It is a compile-time error if C is the class Object
. [jls-15.12.1-100-D.2]
Otherwise, TypeName denotes the interface to be searched, I. [jsr335-15.12.1-100-Z]
Let T be the type declaration immediately enclosing the method invocation. It is a compile-time error if I is not a direct superinterface of T, or if there exists some other direct superclass or direct superinterface of T, J, such that J is a subtype of I. [jsr335-15.12.1-100-Z1]
Let T be the type declaration immediately enclosing the method invocation. It is a compile-time error if T is the class Object
or T is an interface. [jls-15.12.1-100-D.3]
.
NonWildTypeArguments Identifier, then the name of the method is the Identifier and the If TypeName is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only static
methods and interfaces have no static
methods. [jls-15.12.1-100-E.1]
Discussion and motivation:
The TypeName.
super
syntax is overloaded: traditionally, the name refers to a lexically enclosing class, and the target is the superclass of this class (i.e., as if the invocation were an unqualifiedsuper
from the lexically enclosing class).class Superclass { void foo() { System.out.println("Hi"); } } class Subclass1 extends Superclass { void foo() { throw new UnsupportedOperationException(); } Runnable tweak = new Runnable() { void run() { Subclass1.super.foo(); // gets the 'println' behavior } }; }To support invocation of default methods in superinterfaces, the name may also refer to a direct superinterface of the current class or interface, and the target is that superinterface.
interface Superinterface { void foo() default { System.out.println("Hi"); } } class Subclass2 implements Superinterface { void foo() { throw new UnsupportedOperationException(); } void tweak() { Superinterface.super.foo(); // gets the 'println' behavior } }No syntax supports a combination of these forms—invoking a superinterface method of a lexically enclosing class (i.e., as if the invocation were of the form Interface
.
super
from the lexically enclosing class).class Subclass3 implements Superinterface { void foo() { throw new UnsupportedOperationException(); } Runnable tweak = new Runnable() { void run() { Subclass3.Superinterface.super.foo(); // NOT SUPPORTED } }; }There is unlikely to be much need for such syntax; the workaround is to introduce a private method in the lexically enclosing class that performs the interface
super
call.
Compare JLS 15.12.2.5
...
It is possible that no method is the most specific, because there are two or more methods that are maximally specific. In this case: [jls-15.12.2.5-530]
abstract
abstract
or default, However, the most specific method is considered i) to be abstract
, and ii) to throw a checked exception if and only if that exception or its erasure is declared in the throws
clauses of each of the maximally specific methods. [jls-15.12.2.5-530-A-2.1]
Compare JLS 15.12.3
...
If the method invocation has, before the left parenthesis, the form ClassName TypeName .
super
.
NonWildTypeArgumentsopt Identifier, then: [jls-15.12.3-140]
abstract
, a compile-time error occurs. [jls-15.12.3-140-A]
The previous check is redundant: the same error is asserted in 15.12.1.
...
Discussion and motivation:
In the case that a superinterface overrides a method declared in a grandparent interface, this rule prevents the child from "skipping" the override by simply adding the grandparent to its list of direct superinterfaces. The appropriate way to access functionality of a grandparent is through the direct superinterface, and only if that interface chooses to expose the desired behavior. (Alternately, the developer is free to define his own additional superinterface that exposes the desired behavior with asuper
method invocation.)
Compare JLS 15.12.4.1
There are several cases to consider, depending on which of the five productions for MethodInvocation (15.12) is involved: [jls-15.12.4.1-100]
...
.
super
, is involved, then if TypeName denotes a class, the target reference is the value of .
this
; otherwise, the target reference is the value of this
. [jls-15.12.4.1-120-D]
...
Compare JLS 6
...
Access control (6.6) can be specified in a class, interface, method, or field declaration to control when access to a member is allowed. Access is a different concept from scope. Access specified the part of the program text within which the declared entity can be referred to be a qualified name, a field access expression (15.11), or a method invocation expression (15.12) in which the method is not specified by a simple name. In the absence of an access modifier, most declarations have package access, allowing access anywhere within the package that contains its declaration; other possibilities are public
, protected
, and private
.
...
Compare JLS 6.6.1
public
, then it may be accessed by any code, provided that the compilation unit (7.3) in which it is declared is observable. [jls-6.6.1-100-B] If a top level class or interface type is not declared declared with package access, then it may be accessed only from within the package in which it is declared. [jls-6.6.1-100-B.1]public
A class or interface declared without an access modifier implicitly has package access. [jsr335-6.6.1-100-B.2]
public
, then access is permitted. [jls-6.6.1-100-D-1] All members of interfaces lacking access modifiers are implicitly public
. [jls-6.6.1-100-D-1.1]
protected
, then access is permitted only when one of the following is true: [jls-6.6.1-100-D-2]
A class member or constructor declared without an access modifier implicitly has package access. [jsr335-6.6.1-100-D-4.1]
private
, ...
Example 6.6-4. Access to Default Package-Access Fields, Methods, and Constructors
If none of the access modifiers public
, protected
, or private
are specified, a class member or constructor has package access: it is accessible throughout the package that contains the declaration of the class in which the class member is declared, but the class member or constructor is not accessible in any other package.
If a public
class has a method or constructor with default package access, then this method or constructor is not accessible to or inherited by a subclass declared outside this package.
...
Incidental uses of the word "default" or "none" in reference to accessibility should also be replaced with "package" in the following sections: 4.4, 7.4.1, 8.4.8.3, 12.3.3, 13, 13.4.7, 15.12.2.1, 15.12.4.3.
Compare JLS 7.6
...
By default In the absence of an access modifier, the top level types declared in a package have package access: they are accessible only within the compilation units of that package. but A type may be declared to be public
to grant access to the type from code in other packages (6.6, 8.1.1, 9.1.1).