4

Assume I have this class:

public abstract class GraphEdge implements Comparable {

    public abstract double getLength() throws DependencyFailureException;

    @Override
    public int compareTo(Object obj) {
        return Double.compare(getLength(), ((GraphEdge)obj).getLength());
    }
}

Let's not worry about checking the type of obj in compareTo at this moment. getLength() is throwing the exception DependencyFailureException if its dependency is failing. Since getLength() throws an exception, compareTo is giving compile time error as the DependencyFailureException is unhandled.

I don't know if try/catch is the best thing I can do here, as if the exception happened in the getLength(), that means the length of this edge is not meaningful any more and comparing it to another double is not helping. I think if exception happened from getLength(), it should just get surface to the top of the call hirachey.

DependencyFailureException is an custom exception that I can change, if necessary.

What should I do to make the GraphEdge comparable?

jamesdeath123
  • 4,268
  • 11
  • 52
  • 93
  • You wouldn´t need to mind the type of `obj` if you´d be making use of the generics.. – SomeJavaGuy Apr 26 '16 at 05:46
  • @KevinEsche indeed. It's not my concern at this moment though as my main question is about exception handling. – jamesdeath123 Apr 26 '16 at 05:47
  • You´re also having multiple compile time errors. You can´t define an abstract method in an non abstract class. You can´t invoke `compareTo` on primitives. – SomeJavaGuy Apr 26 '16 at 05:49
  • @KevinEsche updated the question so that the syntax won't be the focus. Thanks for mentioning them though. – jamesdeath123 Apr 26 '16 at 05:53
  • What do you *want* to happen if `getLength()` throws an exception? Should that cause the comparison to fail with an unchecked exception? Do you want to continue the overall operation but with the problematic item logically sorting after all non-problematic ones? – Jon Skeet Apr 26 '16 at 05:53
  • @JonSkeet question updated:) good point! – jamesdeath123 Apr 26 '16 at 05:58
  • Do you definitely want `DependencyFailureException` to be a checked exception? Will you *ever* want to catch it and recover? If not, just make it extend `RuntimeException`. – Jon Skeet Apr 26 '16 at 05:59

3 Answers3

2

As mentioned above you can simply wrap it up in Unchecked exception and that will work for you.

@Override
public int compareTo(Object o) {

    try {
        return getLength().compareTo(((GraphEdge)obj).getLength()));
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(), e);
    }
    return 0;
}
Kulbhushan Singh
  • 627
  • 4
  • 20
1

Make DependencyFailureException a runtime exception or surround your return in a try catch block.

public class GraphEdge implements Comparable {

    public abstract double getLength() throws DependencyFailureException;

    @Override
    public int compareTo(Object obj) {
            try {
               return getLength().compareTo(((GraphEdge)obj).getLength()));
            } catch (RuntimeException ex) {
                 throw ex;
            } catch (DependencyFailureException ex) {
                 return -1; // or appropriate error value
            }
    }
}
mirmdasif
  • 6,014
  • 2
  • 22
  • 28
  • 3
    Note that this breaks the `Comparable` contract. Care needs to be taken to be consistent here. – Jon Skeet Apr 26 '16 at 05:54
  • 1
    try/catch seems is a good idea. However if the getLength() is getting exception, I think I should just stop the whole process and throw the exception out to the top of the call hirachey. Is it a way to do so? – jamesdeath123 Apr 26 '16 at 05:55
  • 1
    I feel the better option would be to wrap the `DependencyFailureException` into an `IllegalArgumentException` and throw it from the `compareTo` method.. – Codebender Apr 26 '16 at 05:56
  • @Codebender java.lang.Comparable#compareTo only throws NullPointerException or ClassCastException from its documentation; neither seems appropriate for my case... – jamesdeath123 Apr 26 '16 at 06:00
  • @jamesdeath123 Edited – mirmdasif Apr 26 '16 at 06:02
  • Your modification still breaks the `Comparable` contract. If `a.getLength()` throws a `DependencyFailureException`, and `b.getLength()` doesn't throw an exception, both `a.compareTo(b)` and `b.compareTo(a)` return `-1`. This can cause the standard sort algorithm of Java to throw an `IllegalArgumentException`. – Hoopje Apr 26 '16 at 06:42
0

When you are implementing an interface(or generally when you are overloading a method) you are not allowed to:

      "declare any new checked exceptions for an implementation method".

So you have to define an strategy when the exception occurs in the case of not being able to measure the length and explicitly return an integer value in compareTo method.

Shr.Sa
  • 1
  • 1