0

I have 2 objects from two different classes sharing an attribute of common type (IpAddress which contains all information about the subnet as well). Now, IpAddress is a user define type and I have a function setSecondaryRouter() which can mutate a property of this type. To make the program run as expected I need an invariant (or 2 invariants really) to hold. This is checked in the function setSecondaryRouter(). However, I want to set this property secondaryRouter to be the same in the second object as the first. This kind of implies that the invariant already holds the second time I use setSecondaryRouter(). Due to this I know that the function will not throw.

The problem is that my compiler "helps" to ensure that I do not have uncaught exceptions by not compiling unless I add a try-catch clause or add a throws declaration the caller function (thus helping to solve a non existing problem). What I want to do is to tell Java that this exception will not be thrown. Compare this with the nothrow keyword in c++. I know similar questions are already posted, like the following

Is there any standard annotation to indicate nothrow semantics in Java?

But my question differ in that I do not want to add a throw, or try-catch clause to specific exceptions which I know will not be thrown!

Also one of the expressions is an IllegalArgumentException. Can this exception be the reason that I have to handle the exceptions?

Community
  • 1
  • 1
patrik
  • 4,262
  • 4
  • 21
  • 41

3 Answers3

2

A distinction must be drawn between checked and unchecked exceptions to answer this question:

  • If a method does not declare that it throws a checked exception, it cannot throw an exception of that type (or one of its subtypes):

    void doSomething() {
      throw new Exception();  // Illegal, without throws Exception on doSomething();
    }
    

    As such, you know that a checked exception is not thrown by a method if it is not declared throwing that exception.

    Checked exceptions are intended to be caught, since they are supposed to indicate conditions from which you can recover, so you need to know that they occurred. e.g. IOException: if you try again later, the file might exist, the disk might have space on it, the network might be back up (etc).

  • A method can throw an unchecked exception without declaring that it does; but similarly, you don't need to put in any work to catch it if you don't want to (e.g. because you know that it cannot possibly be thrown). As such, you can never guarantee that a particular RuntimeException is not thrown by a method - maybe it's not thrown directly by the method you called, but it could be thrown by a method that calls (now or in future implementations).

    Unchecked exceptions are not really intended to be caught, since they are supposed to indicate unrecoverable errors, like programming errors. e.g. NullPointerException: you can call the same method with the same parameters, but it'll still fail, because you're running the same code.

Andy Turner
  • 122,430
  • 10
  • 138
  • 216
  • Ahh, ok I see, it is the other checked Exception (non mentioned, called `InternalException` and what it means is irrelevant), which causes trouble then. So you mean that there is no way to tell java to __not handle__ a checked exception since I know that this is handled earlier? Answer that and I will accept (meaning that I will pay for what I do not use...). – patrik Apr 14 '16 at 16:15
  • That is correct. You always have to handle a checked exception by catching or propagating it. – Andy Turner Apr 14 '16 at 16:17
1

The java.lang.IllegalArgumentException is a Runtime Exception, so it is not taken into consideration by the compiler.

If the exception is possibly thrown for the first use of setSecondaryRouter(), you must declare it.

Maybe you could declare a new method cloneFirstRouterToSecondRouter, something like following, catching your Exceptions.

    public void cloneFirstRouterToSecondRouter(){
      try{
         setSecondaryRouter();
      catch(Exception e){
         // should never occur
      }
    }
Loic Mouchard
  • 951
  • 5
  • 19
  • Note that code paths for cases that "should never occur" should always do something in case they do, e.g. `throw new AssertionError(e);`, so you know [quite how "never" they occur in practice](https://en.wikipedia.org/wiki/Murphy%27s_law). – Andy Turner Apr 14 '16 at 16:13
  • :( Ok I see, thats annoying. I guess no "it is your own fault" exist in Java. Big brother oracle enforces us to do the right thing even if we know "the wrong thing will never occur", thus enforcing performance penalties. Anyway thanks for the suggestion – patrik Apr 14 '16 at 16:20
0

It is impossible to prevent a method from throwing exceptions. This is because the JVM may cause a method to throw a VirtualMachineError at anytime. In particular, a method could throw an OutOfMemoryError even if it does not directly or indirectly allocate memory itself (using a new operator). This is not a merely theoretical concern: some concurrent garbage collectors will do this if a garbage collection thread takes too long.

Raedwald
  • 40,290
  • 35
  • 127
  • 207