问题
In the book "Oracle Certified Professional Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805 A Comprehensive OCPJP 7 Certification Guide" by S G Ganesh and Tushar Sharma, it's stated
"if a method is declared in 2 or more interfaces, and if that method declares to throw different exceptions in the throws clause, the implementation should list all these exceptions" (page 347)
Well, then I've tried this
public interface I1 {
public void x() throws I1Exception;
}
public interface I2 {
public void x() throws I2Exception;
}
public class I1Exception extends Exception {
}
public class I2Exception extends Exception {
}
public class Sample implements I1, I2{
@Override
public void x() throws I2Exception {
throw new I2Exception();
}
@Override
public void x() throws I1Exception {
throw new I1Exception();
}
}
Of course, the exception is not part of the method signature, so the compiler complains that the second method is duplicated.
On the other hand
@Override
public void x() throws I1Exception, I2Exception {
throw new I1Exception();
}
Is not compatible with both interfaces because it declares more checked exceptions than any one of the methods of each interface, taken separately.
This means that I don't understood what the book says or does that mean the book statement is innacurate?
回答1:
That specific sentence of the book seems to be incorrect. The Java Language Specification has more reasonable clause explaining this issue (which I think is the part referred by the book).
When interfaces are involved, more than one method declaration may be overridden by a single overriding declaration. In this case, the overriding declaration must have a throws clause that is compatible with all the overridden declarations (§9.4.1).
So in this case, one that is compatible with both declarations would be
@Override
public void x() {
}
In both declarations had common exceptions they could have included in the declaration.
interface I1 {
public void x() throws I1Exception, I2Exception;
}
interface I2 {
public void x() throws I2Exception;
}
then
@Override
public void x() throws I2Exception {
}
Or alternatively in your example, if you had something like
class I1Exception extends I2Exception {
}
class I2Exception extends Exception {
}
Then a compatible method declaration could be written as
@Override
public void x() throws I1Exception {
}
回答2:
After giving it a second thought, I think the intention of the book was to say that you have to satisfy both interfaces at the same time.
So the method should throw (roughly speaking) an intersection of sets of exceptions of both methods. If these sets don't intersect then the method can't throw anything. So this:
@Override
public void x() {
}
Is OK for both interfaces.
(It's a bit more complicated because of inheritance, but you get the idea.)
So from my point of view
"if a method is declared in 2 or more interfaces, and if that method declares to throw different exceptions in the throws clause, the implementation should list all these exceptions" (page 347)
can't be correct because it does not work in practice. You (in most cases) can't list all of these exceptions in an implementation. There are exceptions like unchecked exceptions or identical/compatible sets of exceptions.
However I could not find normative reference in JLS for this.
回答3:
I think that the book states that you can choose which method you want to implement, but can't implement both of them (didn't try it, but that's how I would understand it).
the implementation should list all these exceptions
probably means all exceptions that one method declares in the throws
clause.
回答4:
The error is having two methods in the same class with the same name that get no parameters. In java you can have different methods with the same name only if they get different parameters: for example
public int i (int a);
public int i ();
回答5:
The set of checked exceptions that a method can throw is the intersection of the sets of checked exceptions that it is declared to throw in all applicable types, not the union. As a result, the x() on an object can’t throw any checked exceptions at all and is permitted.
@Override
public void x() {
}
It illustrates the interaction of multiple inherited throws clauses, which reduces rather than increases the number of exceptions that a method is permitted to throw. This don’t generally cause subtle bugs, but they can be a bit surprising the first time you see them.
来源:https://stackoverflow.com/questions/26300828/class-implements-two-interfaces-with-the-same-method-but-different-checked-excep