Faking abstract methods using exceptions in Java


问题 (Question)

I've been asked this question and am frankly stumped:

Instead of writing abstract methods we could try to fake them with exceptions, like this:

public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");

What would be the purpose of doing this and can anyone provide an example of code for an abstract method that the above is trying to fake? Any help is greatly appreciated. Thank you.



public int someMethod(int someparameter) {
    throws new RuntimeException("unimplemented");


最佳答案 (Best Answer)

I can think of one (possibly) valid use case: You have an abstract class, and a number of other classes throughout your project that extended it. (Or the abstract class is in an open-source library, so you have no idea what other classes throughout the universe might be extended from it.) Now, you find that it's useful to add new abstract methods to this class. But if you add abstract methods to the class, this breaks every other class that has already extended it, because those classes need to be changed to contain override for the new methods. So I can see how, in some cases, it might be considered more feasible to add them as non-abstract methods and have them throw exceptions just in case a new class that extends it uses the new methods but forgets to write an overriding method. It won't be caught at compile-time, but at least it might be caught during testing.

I'm not sure how legitimate this reason is, since it's also possible to define a new abstract class NewImprovedWhatever that extends the old one, to contain the new methods. That may pose its own maintenance challenges, though. I'm not sure.

I did notice that Java defines an abstract class java.net.SocketImpl, that contains two non-abstract methods, shutdownInput() and shutdownOutput(), whose default implementation is to throw an exception:

protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");

The comments indicate that they were added in 1.3, so perhaps that's the exact reason it was done this way, i.e. not to require modification of other classes that already extended SocketImpl. But I don't know for sure.

In any case, a design like this would surely be really bad code, if the class were designed that way from scratch. But the nice O-O concepts we learn about in class aren't always so nice in practice when existing code has to be modified.




protected void shutdownInput() throws IOException {
  throw new IOException("Method not implemented!");



答案 (Answer) 2

The purpose of doing this would be to purposefully write BAD CODE.
If one wants to confuse its readers and want them to feel the agony of going through their code, then one writes such code.
It also shows lack of designing skills in the code.
A poorly written API will have such code.
Don't do that.


答案 (Answer) 3

I have sometimes thrown UnsupportedOperationException from a method whose functionality has not yet been implemented. (There is also a NotImplementedException in Apache Commons which is a subclass of UnsupportedOperationException.) This was always meant as a placeholder and a message to others using the related class or service that the method is not yet complete. Such code never made it to production, however.

有时候我会抛出UnsupportedOperationException异常从法的功能尚未实施。(还有一个在Apache Commons notimplementedexception这是UnsupportedOperationException异常的一个子类。)这意味着作为一个占位符,一个消息给他人使用相关的类或方法是尚未完成的服务。这样的代码没有生产,但。