问题
Let's say I have the following two class/interface definitions:
public abstract class FooClass {
public abstract void doFoo();
}
and
public interface BarInterface {
public void doBar();
}
If I want to make an anonymous inner class that extends/implements both, do I need to do this:
public abstract class BothClass extends FooClass implements BarInterface {}
...
new BothClass() {
public void doFoo() {
System.out.println("Fooooooooo!!!!");
}
public void doBar() {
System.out.println("Baaaaaaaar!!!!");
}
}.doBar();
Or is there a short-cut that allows me to not define BothClass
? Something like this, maybe:
new (FooClass implements BarInterface)() {
public void doFoo() {
System.out.println("Fooooooooo!!!!");
}
public void doBar() {
System.out.println("Baaaaaaaar!!!!");
}
}.doBar();
(This idea gives me several errors, none of which are helpful here)
回答1:
Let's go to the JLS:
An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler.
where a class instance creation expression is
ClassInstanceCreationExpression:
new TypeArgumentsopt TypeDeclSpecifier TypeArgumentsOrDiamondopt
( ArgumentListopt ) ClassBodyopt
Primary . new TypeArgumentsopt Identifier TypeArgumentsOrDiamondopt
( ArgumentListopt ) ClassBodyopt
TypeArgumentsOrDiamond:
TypeArguments
<>
ArgumentList:
Expression
ArgumentList , Expression
So, no, the Java language specification does not allow any shortcuts for making your anonymous class implement more interfaces than the type you're sub-typing.
So, to determine the type of the anonymous class
If the class instance creation expression ends in a class body, then the class being instantiated is an anonymous class. Then:
- If T denotes an interface, then an anonymous direct subclass of Object that implements the interface named by T is declared.
[...]
- Let T be the type named by the Identifier and any type arguments. An anonymous direct subclass of the class named by T is declared. The body of the subclass is the ClassBody given in the class instance creation expression.
Your alternative is the way to do it.
You can also use local classes.
回答2:
An anonymous class
FooClass f = new FooClass() {
public void doFoo() {}
};
is just a convenient shorthand for a local class definition with a generated name
class $anon extends FooClass {
public void doFoo() {}
}
FooClass f = new $anon();
If you want to implement interfaces just write the local class definition explicitly
class LocalFoo extends FooClass implements BarInterface {
// method declarations here
}
LocalFoo lf = new LocalFoo();
来源:https://stackoverflow.com/questions/21515693/instantiating-anonymous-inner-classes-in-java-with-additional-interface-implemen