82

Consider the following code:

public Object getClone(Cloneable a) throws TotallyFooException {

    if (a == null) {
        throw new TotallyFooException();
    }
    else {
        try {
            return a.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
    //cant be reached, in for syntax
    return null;
}

The return null; is necessary since an exception may be caught, however in such a case since we already checked if it was null (and lets assume we know the class we are calling supports cloning) so we know the try statement will never fail.

Is it bad practice to put in the extra return statement at the end just to satisfy the syntax and avoid compile errors (with a comment explaining it will not be reached), or is there a better way to code something like this so that the extra return statement is unnecessary?

Dirk
  • 30,623
  • 8
  • 82
  • 102
yitzih
  • 3,018
  • 3
  • 27
  • 44
  • 25
    Your method takes an `Object` parameter. If `a` isn't a class that supports the `clone` method (or is this defined in `Object`?) or if an error occurs during the `clone` method (or any other mistake I can't think of right now), an Exception could be thrown and you would reach the return statement. – Arc676 Nov 19 '15 at 12:48
  • For a null check you could use Objects.requireNonNull(a); which is a bit nicer of a syntax. See: http://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#requireNonNull-T- – Kuchi Nov 19 '15 at 12:52
  • 1
    @AndyTurner that's wrong the Clonable interface dos not require to implement the clone() method. It's a common convention. I would recommend to have a look here: http://stackoverflow.com/questions/26434278/effective-java-item-11-override-clone-judiciously – Kuchi Nov 19 '15 at 13:03
  • 1
    Your question is good but the example in your question does not illustrate the point: How to react to a situation which *cannot* occur. I definitely think (as expressed in my answer) that throwing an `InternalError` and not a exception is the way to go. – wero Nov 19 '15 at 13:06
  • 2
    The exception thrown by bugs shouldn't be a checked exception. – CodesInChaos Nov 19 '15 at 14:18
  • 26
    Your assumption that the final return can't be reached is wrong. It is totally valid for a class that implements `Cloneable` to throw a `CloneNotSupportedException`. Source: [javadocs](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone%28%29) – Cephalopod Nov 19 '15 at 14:32
  • Slightly related: http://stackoverflow.com/questions/9570823/missing-return-statement-but-i-know-it-is-there – Sebastian Mach Nov 19 '15 at 14:52
  • 21
    The code which you have commented as "cant be reached" can be reached. As mentioned above there's a code path from the CloneNotSupportedException to this line. – David Waterworth Nov 19 '15 at 16:51
  • 1
    Does this code even compile? The Eclipse compiler gives an error for `a.clone()` since `clone` is not declared in `Clonable` and is not a public method of `Object`. – Theodore Norvell Nov 19 '15 at 21:20
  • 7
    The core question here: If you are assuming the class you are calling supports cloning, why are you catching the exception at all? Exceptions *should* be thrown for exceptional behaviour. – deworde Nov 20 '15 at 09:07
  • 1
    @Kuchi Except that it throws a null pointer exception; you may have a valid reason to throw TotallyFoo instead (being able to be more specific about where null was detected being the primary one) – deworde Nov 20 '15 at 09:11
  • I have an aversion to multiple exit points from functions. Normally I will set up a return variable with a default value, and change that value within the function, with just having a return at the end. – Kickstart Nov 20 '15 at 10:18
  • 3
    @wero I would go for `AssertionError` instead of `InternalError`. The latter seems to be for special use if something in the JVM goes wrong. And you basically assert that the code is not reached. – kap Nov 20 '15 at 13:12
  • 1
    I'm no java coder, so I might be mistaken, but if I did something like that I C# my boss would rightfully shout my head off. I think the `CloneNotSupportedException` must have been catched in the caller, and if - by any reason - it s not possible, this routine should be be called from a wrapper with the sole purpose to catch that exception if it is raised. – mg30rg Nov 20 '15 at 13:29
  • 2
    Early returns can be bad, especially if the function is long. It shoudl be possible in most (if not all) cases to refactor the function so it has a single return, at the end of the function. Otherwise, someone maintaining the code may not realize that control has left the function early and introduce a bug. – Steve Nov 20 '15 at 18:41
  • @deworde CloneNotSupportedException is a checked exception, which means you're required to catch it (or declare it as being throw-able from the method) – user253751 Nov 21 '15 at 11:18
  • While the code given may be only an example, I generally don't catch exceptions; when they happen, they bubble up to a handler. I would have coded that method with a one-liner. Java is much clearer when it isn't junked up with unhelpful null tests and exception handling. In this case, none of those these exceptions add useful information. – Tony Ennis Nov 21 '15 at 14:34
  • @immibis Agreed, but without further context, why is throwing TotallyFoo better, considering the method getClone can't possibly be considered to be abstracting away cloning? – deworde Nov 21 '15 at 18:01
  • 1
    @Kickstart & Steve While in general randomly returning halfway through a long function is an issue, "top of function" returns are actually far more readable than assigning false and then forcing the programmer to scroll past 200 lines of code baked inside a massive if block just to verify that you do nothing. Not to mention they prevent accidental side-effects when the intent of the early return was do nothing. – deworde Nov 21 '15 at 18:10
  • @deworde The actual method is being used to abstract away the cloning. It is called by many different methods to retrieve a clone of a mutable object so that its contents can be viewed but the object pointer can't be changed to another through this method. The name of the method was changed to getClone to make it obvious what the purpose of it was – yitzih Nov 22 '15 at 03:19
  • @immibis But in that case, if you did get that exception, that would be unexpected behaviour, and the correct response would be to throw an exception and catch in the caller, not to push it downstream to only become a problem when you try to use the clone. If we were anti-exceptions, that would be arguable, but we're already throwing TotesFoo, so that can't be it. – deworde Nov 22 '15 at 07:32
  • @yitzih What I meant by abstracting is that with "getClone() throws CloneNotSupported" the link between method name and exception thrown is obvious, whereas with "activate() throws CloneNotSupported", you'd generally expect the concept of requiring cloning to have been hidden behind a try-catch or a change to type of exception thrown – deworde Nov 22 '15 at 07:39
  • @deworde The caller of `clone` or the caller of `getClone`? – user253751 Nov 22 '15 at 08:12
  • @immibis The caller of getClone() in this case. This method doesn't have any useful behaviour it can convert that CNS exception to, it would be obvious at the caller level why the method has thrown what it threw, and the behaviour would be considered abnormal. So why mask the exception at all? – deworde Nov 22 '15 at 17:46
  • @deworde Because every caller would have to do the exact same thing then? There's nothing meaningful **those** callers can do if a Cloneable object throws a CloneNotSupportedException either. – user253751 Nov 22 '15 at 19:11
  • @immibis There might be, especially as they're the suppliers of the uncloneable, they might have access to a factory or database querier that can generate a duplicate object, or at worst supply a more context appropriate error message. At absolute worst, the caller is now aware this is a potential issue they have to deal with, rather than blindly supplying null down through the process. But even if you're right, what are you especting them to do with the *null value* that's any more meaningful or less "exact same thing"? – deworde Nov 22 '15 at 20:28
  • @deworde If an uncloneable object implements Cloneable, then some programmer somewhere made a mistake, which is basically what AssertionError is for. – user253751 Nov 22 '15 at 21:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95901/discussion-between-deworde-and-immibis). – deworde Nov 23 '15 at 09:20
  • @deworde you can add a message to the the Objects.requireNonNull(a, "Message") See: http://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#requireNonNull-T-java.lang.String- – Kuchi Nov 25 '15 at 18:48

13 Answers13

136

A clearer way without an extra return statement is as follows. I wouldn't catch CloneNotSupportedException either, but let it go to the caller.

if (a != null) {
    try {
        return a.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
}
throw new TotallyFooException();

It's almost always possible to fiddle with the order to end up with a more straight-forward syntax than what you initially have.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • 30
    This illustrates a really good general point. If you find yourself fighting java's requirements it generally means that you are trying to do something in a sub-optimal way. Usually if I feel uncomfortable I step back and take a look at the whole picture and try to figure out if it could be coded in a different way that makes it more clear--generally there is. Most of java's little nitpicks are amazingly helpful once you embrace them. – Bill K Nov 19 '15 at 17:10
  • 3
    @BillK: This code has different semantics though, as pointed out by Maroun Maroun. – Deduplicator Nov 19 '15 at 19:07
  • 5
    `AssertionError` is a built-in class with a similar intention to `TotallyFooException` (which doesn't actually exist). – user253751 Nov 19 '15 at 21:57
  • 5
    @BillK: *"If you find yourself fighting java's requirements it generally means that you are trying to do something in a sub-optimal way."* or that Java decided not to support a feature that makes your life easier. – user541686 Nov 20 '15 at 11:47
  • 1
    I would prefer `if(a == null) throw new TFE("Cannot clone null")` and in the catch block `throw new TFE(e);` – Walter Laan Nov 20 '15 at 12:10
  • 5
    @Mehrdad, ...but looking at it that way doesn't get you anywhere practically useful, unless you're a person working on RFEs for future Java versions or an alternative language. Learning the local idioms has real, practical advantage, whereas blaming the language (any language, unless it has metaprogramming support a-la-LISP to allow adding new syntax yourself) for not supporting the way you first wanted to do something doesn't. – Charles Duffy Nov 20 '15 at 17:57
  • 2
    @Deduplicator the code has different semantics **if and only if** the OP is wrong in his assumptions and the last command can be reached. And if the programmer's assumptions are wrong, it is way better to actively signal that an error has happened that just "swallowing" an unexpected situation and leading to an invalid value or a NPE later in the program execution. – SJuan76 Nov 22 '15 at 18:15
101

It definitely can be reached. Note that you're only printing the stacktrace in the catch clause.

In the scenario where a != null and there will be an exception, the return null will be reached. You can remove that statement and replace it with throw new TotallyFooException();.

In general*, if null is a valid result of a method (i.e. the user expects it and it means something) then returning it as a signal for "data not found" or exception happened is not a good idea. Otherwise, I don't see any problem why you shouldn't return null.

Take for example the Scanner#ioException method:

Returns the IOException last thrown by this Scanner's underlying Readable. This method returns null if no such exception exists.

In this case, the returned value null has a clear meaning, when I use the method I can be sure that I got null only because there was no such exception and not because the method tried to do something and it failed.

*Note that sometimes you do want to return null even when the meaning is ambiguous. For example the HashMap#get:

A return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.

In this case null can indicate that the value null was found and returned, or that the hashmap doesn't contain the requested key.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 4
    Although your points are valid, I would like to point out that this is simply crappy API design. Both methods should return an `Optional` or `Optional`, respectively. Note: this is not a criticism of your answer, rather of the API design of those two methods. (It is, however, a rather common design mistake, that is pervasive throughout not only the entire Java API, but e.g. .NET as well.) – Jörg W Mittag Nov 19 '15 at 17:29
  • 4
    "crappy" is rather harsh if you do not know if Java 8 facilities may be used or not. – Thorbjørn Ravn Andersen Nov 20 '15 at 01:28
  • 2
    But when `null` is *not* a valid return value, returning `null` is an even worse idea. In other words, returning `null` for an unexpected situation is never a good idea. – Holger Nov 20 '15 at 10:02
  • 1
    @Holger What I mean by *not valid* is for example when the user expects to get a value from a data structure that cannot contain `null`, then `null` can never be a "valid" return value in the sense that it must indicate something else rather than a normal return value. In this case, returning it have a special meaning and I don't see anything wrong with that design (of course the user should know how to handle this situation). – Maroun Nov 20 '15 at 10:44
  • 1
    That’s the point: “the user should know how to handle this situation” implies that you have to specify that `null` is a possible return value that the caller has to deal with. That makes it a valid value, and we have the same understanding of “valid” here, as you describe “valid” as “ the user *expects* it and it means something”. But here, the situation is different anyway. The OP states per code comment that he asserts that the `return null;` statement “cant be reached” which implies that returning `null` is wrong. It should be a `throw new AssertionError();` instead… – Holger Nov 20 '15 at 11:17
  • @Holger That's correct. I mentioned that in the first part of my answer and wanted to give a general advice. BTW, by saying "valid return value" I mean a valid **functional** value (that doesn't indicate inability of getting some value). – Maroun Nov 20 '15 at 11:24
  • In the end, `null` always indicates the absence of a valid value; it’s only that some APIs pass through the `null`, thus the special case happened earlier in the program execution then. I.e. when `null` has been stored in a `Map`, it indicates that whoever stored the `null` into the `Map` got it from somewhere. You can always track the source of a `null` to a point where it indicates a special case or the absence of a value. – Holger Nov 20 '15 at 11:31
  • @Holger `null` can indicate whatever the programmer wants it to indicate, or whatever it's most convenient for it to indicate. The language doesn't force you to use it in a particular way. – user253751 Nov 22 '15 at 08:14
26

Is it bad practice to put in the extra return statement at the end just to satisfy the syntax and avoid compile errors (with a comment explaining it will not be reached)

I think return null is bad practice for the terminus of an unreachable branch. It is better to throw a RuntimeException (AssertionError would also be acceptable) as to get to that line something has gone very wrong and the application is in an unknown state. Most like this is (like above) because the developer has missed something (Objects can be none-null and un-cloneable).

I'd likely not use InternalError unless I'm very very sure that the code is unreachable (for example after a System.exit()) as it is more likely that I make a mistake than the VM.

I'd only use a custom exception (such as TotallyFooException) if getting to that "unreachable line" means the same thing as anywhere else you throw that exception.

Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81
  • 3
    As noted elsewhere in the comments, an [`AssertionError`](http://docs.oracle.com/javase/7/docs/api/java/lang/AssertionError.html) could also be a reasonable choice to throw in a ["can't happen"](http://www.catb.org/jargon/html/C/can-t-happen.html) event. – Ilmari Karonen Nov 20 '15 at 22:13
  • 2
    Personally I'd throw a `SomeJerkImplementedClonableAndStillThrewACloneNotSupportedExceptionException`. It would extend `RuntimeException`, obviously. – w25r Nov 25 '15 at 09:38
  • @w25r I'm not using the code above, but answering the underlying question. Given [`Cloneable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html) does not implement a public `clone()` method and `clone()` in object is `protected` the code above does not actually compile. – Michael Lloyd Lee mlk Nov 25 '15 at 09:40
  • I'd not use a passive-aggressive exception just in case it escaped (as funny as it would be for one of our clients to get a `JerkException`, I don't think it would be appreciated). – Michael Lloyd Lee mlk Nov 25 '15 at 10:07
14

You caught the CloneNotSupportedException which means your code can handle it. But after you catch it, you have literally no idea what to do when you reach the end of the function, which implies that you couldn't handle it. So you're right that it is a code smell in this case, and in my view means you should not have caught CloneNotSupportedException.

djechlin
  • 59,258
  • 35
  • 162
  • 290
12

I would prefer to use Objects.requireNonNull() to check if the Parameter a is not null. So it's clear when you read the code that the parameter should not be null.

And to avoid checked Exceptions I would re throw the CloneNotSupportedException as a RuntimeException.

For both you could add nice text with the intention why this shouldn't happen or be the case.

public Object getClone(Object a) {

    Objects.requireNonNull(a);

    try {
        return a.clone();
    } catch (CloneNotSupportedException e) {
        throw new IllegalArgumentException(e);
    }

}
Kuchi
  • 4,204
  • 3
  • 29
  • 37
8

The examples above are valid and very Java. However, here's how I would address the OP's question on how to handle that return:

public Object getClone(Cloneable a) throws CloneNotSupportedException {
    return a.clone();
}

There's no benefit for checking a to see if it is null. It's going to NPE. Printing a stack trace is also not helpful. The stack trace is the same regardless of where it is handled.

There is no benefit to junking up the code with unhelpful null tests and unhelpful exception handling. By removing the junk, the return issue is moot.

(Note that the OP included a bug in the exception handling; this is why the return was needed. The OP would not have gotten wrong the method I propose.)

Tony Ennis
  • 12,000
  • 7
  • 52
  • 73
7

In this sort of situation I would write

public Object getClone(SomeInterface a) throws TotallyFooException {
    // Precondition: "a" should be null or should have a someMethod method that
    // does not throw a SomeException.
    if (a == null) {
        throw new TotallyFooException() ; }
    else {
        try {
            return a.someMethod(); }
        catch (SomeException e) {
            throw new IllegalArgumentException(e) ; } }
}

Interestingly you say that the "try statement will never fail", but you still took the trouble to write a statement e.printStackTrace(); that you claim will never be executed. Why?

Perhaps your belief is not that firmly held. That is good (in my opinion), since your belief is not based on the code you wrote, but rather on the expectation that your client will not violate the precondition. Better to program public methods defensively.

By the way, your code won't compile for me. You can't call a.clone() even if the type of a is Cloneable. At least Eclipse's compiler says so. Expression a.clone() gives error

The method clone() is undefined for the type Cloneable

What I would do for your specific case is

public Object getClone(PubliclyCloneable a) throws TotallyFooException {
    if (a == null) {
        throw new TotallyFooException(); }
    else {
        return a.clone(); }
}

Where PubliclyCloneable is defined by

interface PubliclyCloneable {
    public Object clone() ;
}

Or, if you absolutely need the parameter type to be Cloneable, the following at least compiles.

public static Object getClone(Cloneable a) throws TotallyFooException {
//  Precondition: "a" should be null or point to an object that can be cloned without
// throwing any checked exception.
    if (a == null) {
        throw new TotallyFooException(); }
    else {
        try {
            return a.getClass().getMethod("clone").invoke(a) ; }
        catch( IllegalAccessException e ) {
            throw new AssertionError(null, e) ; }
        catch( InvocationTargetException e ) {
            Throwable t = e.getTargetException() ;
            if( t instanceof Error ) {
                // Unchecked exceptions are bubbled
                throw (Error) t ; }
            else if( t instanceof RuntimeException ) {
                // Unchecked exceptions are bubbled
                throw (RuntimeException) t ; }
            else {
                // Checked exceptions indicate a precondition violation.
                throw new IllegalArgumentException(t) ; } }
        catch( NoSuchMethodException e ) {
            throw new AssertionError(null, e) ; } }
}
Theodore Norvell
  • 15,366
  • 6
  • 31
  • 45
  • The compile-time error got me to wondering why `Cloneable` does not declare `clone` as a public method that does not throw any checked exceptions. There is an interesting discussion at http://bugs.java.com/view_bug.do?bug_id=4098033 – Theodore Norvell Nov 19 '15 at 23:22
  • 2
    I'd like to mention that the vast majority of Java code doesn't use Lisp-esque braces, and you'll get dirty looks if you try to use that in a job environment. – Nic Nov 20 '15 at 12:18
  • 1
    Thanks for that. Actually I wasn't very consistent. I edited the answer to consistently use my preferred brace style. – Theodore Norvell Nov 20 '15 at 17:49
5

Is having a return statement just to satisfy syntax bad practice?

As others have mentioned, in your case this does not actually apply.

To answer the question, though, Lint type programs sure haven't figured it out! I have seen two different ones fight it out over this in a switch statement.

    switch (var)
   {
     case A:
       break;
     default:
       return;
       break;    // Unreachable code.  Coding standard violation?
   }

One complained that not having the break was a coding standard violation. The other complained that having it was one because it was unreachable code.

I noticed this because two different programmers kept re-checking the code in with the break added then removed then added then removed, depending on which code analyzer they ran that day.

If you end up in this situation, pick one and comment the anomaly, which is the good form you showed yourself. That's the best and most important takeaway.

Jos
  • 189
  • 2
5

It isn't 'just to satisfy syntax'. It is a semantic requirement of the language that every code path leads to a return or a throw. This code doesn't comply. If the exception is caught a following return is required.

No 'bad practice' about it, or about satisfying the compiler in general.

In any case, whether syntax or semantic, you don't have any choice about it.

user207421
  • 305,947
  • 44
  • 307
  • 483
2

I would rewrite this to have the return at the end. Pseudocode:

if a == null throw ...
// else not needed, if this is reached, a is not null
Object b
try {
  b = a.clone
}
catch ...

return b
Pablo Pazos
  • 3,080
  • 29
  • 42
  • As a related side note, you can _almost_ always refactor your code to have the return statement at the end. In fact is a good coding standard, because makes the code a little easier to maintain and fix bugs, since you don't have to consider many exit points. Also it would be a good practice to declare all the variables at the beginning of the method, for the same reason. Also consider that having the return at the end might need to declare more variables, like in my solution, I needed the extra "Object b" variable. – Pablo Pazos Nov 21 '15 at 01:48
2

No one mentioned this yet so here goes:

public static final Object ERROR_OBJECT = ...

//...

public Object getClone(Cloneable a) throws TotallyFooException {
Object ret;

if (a == null) 
    throw new TotallyFooException();

//no need for else here
try {
    ret = a.clone();
} catch (CloneNotSupportedException e) {
    e.printStackTrace();
    //something went wrong! ERROR_OBJECT could also be null
    ret = ERROR_OBJECT; 
}

return ret;

}

I dislike return inside try blocks for that very reason.

rath
  • 3,655
  • 1
  • 40
  • 53
2

The return null; is necessary since an exception may be caught, however in such a case since we already checked if it was null (and lets assume we know the class we are calling supports cloning) so we know the try statement will never fail.

If you know details about the inputs involved in a way where you know the try statement can never fail, what is the point of having it? Avoid the try if you know for sure things are always going to succeed (though it is rare that you can be absolutely sure for the whole lifetime of your codebase).

In any case, the compiler unfortunately isn't a mind reader. It sees the function and its inputs, and given the information it has, it needs that return statement at the bottom as you have it.

Is it bad practice to put in the extra return statement at the end just to satisfy the syntax and avoid compile errors (with a comment explaining it will not be reached), or is there a better way to code something like this so that the extra return statement is unnecessary?

Quite the opposite, I'd suggest it's good practice to avoid any compiler warnings, e.g., even if that costs another line of code. Don't worry too much about line count here. Establish the reliability of the function through testing and then move on. Just pretending you could omit the return statement, imagine coming back to that code a year later and then try to decide if that return statement at the bottom is going to cause more confusion than some comment detailing the minutia of why it was omitted because of assumptions you can make about the input parameters. Most likely the return statement is going to be easier to deal with.

That said, specifically about this part:

try {
    return a.clone();
} catch (CloneNotSupportedException e) {
   e.printStackTrace();
}
...
//cant be reached, in for syntax
return null;

I think there's something slightly odd with the exception-handling mindset here. You generally want to swallow exceptions at a site where you have something meaningful you can do in response.

You can think of try/catch as a transaction mechanism. try making these changes, if they fail and we branch into the catch block, do this (whatever is in the catch block) in response as part of the rollback and recovery process.

In this case, merely printing a stacktrace and then being forced to return null isn't exactly a transaction/recovery mindset. The code transfers the error-handling responsibility to all the code calling getClone to manually check for failures. You might prefer to catch the CloneNotSupportedException and translate it into another, more meaningful form of exception and throw that, but you don't want to simply swallow the exception and return a null in this case since this is not like a transaction-recovery site.

You'll end up leaking the responsibilities to the callers to manually check and deal with failure that way, when throwing an exception would avoid this.

It's like if you load a file, that's the high-level transaction. You might have a try/catch there. During the process of trying to load a file, you might clone objects. If there's a failure anywhere in this high-level operation (loading the file), you typically want to throw exceptions all the way back to this top-level transaction try/catch block so that you can gracefully recover from a failure in loading a file (whether it's due to an error in cloning or anything else). So we generally don't want to just swallow up an exception in some granular place like this and then return a null, e.g., since that would defeat a lot of the value and purpose of exceptions. Instead we want to propagate exceptions all the way back to a site where we can meaningfully deal with it.

0

Your example is not ideal to illustrate your question as stated in the last paragraph:

Is it bad practice to put in the extra return statement at the end just to satisfy the syntax and avoid compile errors (with a comment explaining it will not be reached), or is there a better way to code something like this so that the extra return statement is unnecessary?

A better example would be the implementation of clone itself:

 public class A implements Cloneable {
      public Object clone() {
           try {
               return super.clone() ;
           } catch (CloneNotSupportedException e) {
               throw new InternalError(e) ; // vm bug.
           }
      }
 }

Here the catch clause should never be entered. Still the syntax either requires to throw something or return a value. Since returning something does not make sense, an InternalError is used to indicate a severe VM condition.

wero
  • 32,544
  • 3
  • 59
  • 84
  • 5
    The superclass throwing a `CloneNotSupportedException` is *not* a "vm bug" -- it's perfectly legal for a `Cloneable` to throw it. It *might* constitute a bug in your code and/or in the superclass, in which case wrapping it in a `RuntimeException` or possibly an `AssertionError` (but not an `InternalError`) might be appropriate. Or you could just duck the exception -- if your superclass doesn't support cloning, then neither do you, so `CloneNotSupportedException` is semantically appropriate. – Ilmari Karonen Nov 19 '15 at 22:42
  • @IlmariKaronen you may want to send this advice to Oracle so that they can correct all clone methods within the JDK which throw an InternalError – wero Nov 20 '15 at 00:47
  • @wero Somebody undoubtedly already has, but this smacks of legacy code. – deworde Nov 20 '15 at 09:10