[jdk1.5.0_01] assert false

Discussion in 'Java' started by Paul Chapman, Feb 4, 2005.

  1. Paul Chapman

    Paul Chapman Guest

    I've just updraded to jdk1.5.0_01. I've already found that generics improve
    my code.

    I've just been rewriting some base-class methods which should never be
    called. Previously they might look like:

    protected int method()
    {
    throw new RuntimException();
    }

    The compiler doesn't complain that there's no return statement, presumably
    because it knows that the throw means the method will never return normally.

    I am rewriting these to use assert, thus:

    protected int method()
    {
    assert false;
    }

    This seems to me to be a reasonable thing to do, and an improvement. The
    new compiler complains that there is no return statement. I think it might
    be improved to recognize that the assertion will always throw an exception.

    Any views?

    Cheers, Paul
     
    Paul Chapman, Feb 4, 2005
    #1
    1. Advertising

  2. Paul Chapman

    Andy Hill Guest

    "Paul Chapman" <-online.co.uk> wrote:

    >I've just updraded to jdk1.5.0_01. I've already found that generics improve
    >my code.
    >
    >I've just been rewriting some base-class methods which should never be
    >called. Previously they might look like:
    >
    >protected int method()
    >{
    > throw new RuntimException();
    >}
    >
    >The compiler doesn't complain that there's no return statement, presumably
    >because it knows that the throw means the method will never return normally.
    >
    >I am rewriting these to use assert, thus:
    >
    >protected int method()
    >{
    > assert false;
    >}
    >
    >This seems to me to be a reasonable thing to do, and an improvement. The
    >new compiler complains that there is no return statement. I think it might
    >be improved to recognize that the assertion will always throw an exception.
    >
    >Any views?
    >
    >Cheers, Paul
    >

    Assertions can be turned off or on (unlike an exception throw). So what
    happens in your code when the assert is turned off? Compiler error make sense,
    now?
     
    Andy Hill, Feb 4, 2005
    #2
    1. Advertising

  3. Paul Chapman

    Jim Guest

    On Fri, 4 Feb 2005 20:36:53 -0000, "Paul Chapman"
    <-online.co.uk> wrote:

    >I've just updraded to jdk1.5.0_01. I've already found that generics improve
    >my code.
    >
    >I've just been rewriting some base-class methods which should never be
    >called. Previously they might look like:
    >
    >protected int method()
    >{
    > throw new RuntimException();
    >}
    >
    >The compiler doesn't complain that there's no return statement, presumably
    >because it knows that the throw means the method will never return normally.
    >
    >I am rewriting these to use assert, thus:
    >
    >protected int method()
    >{
    > assert false;
    >}
    >
    >This seems to me to be a reasonable thing to do, and an improvement. The
    >new compiler complains that there is no return statement. I think it might
    >be improved to recognize that the assertion will always throw an exception.
    >
    >Any views?
    >
    >Cheers, Paul
    >

    Try

    public class UnsupportedOperationException extends RuntimeException

    "Thrown to indicate that the requested operation is not supported."


    Jim
     
    Jim, Feb 4, 2005
    #3
  4. Paul Chapman

    Guest

    Jim wrote:
    > Try
    >
    > public class UnsupportedOperationException extends RuntimeException
    >
    > "Thrown to indicate that the requested operation is not supported."
    >
    >
    > Jim

    This is a good suggestion. Any reason the methods aren't abstract ?
     
    , Feb 5, 2005
    #4
  5. Paul Chapman

    Paul Chapman Guest

    Andy,

    > Assertions can be turned off or on (unlike an exception throw). So

    what
    > happens in your code when the assert is turned off? Compiler error make

    sense,
    > now?


    Hmm, yes. :)

    I guess I might put the throws back in. They should never be executed, so
    there's no performance penalty.

    Cheers, Paul
     
    Paul Chapman, Feb 6, 2005
    #5
  6. Paul Chapman

    Paul Chapman Guest

    I wrote:

    > I've just been rewriting some base-class methods which should never be
    > called. ...


    This made me think.

    abstract class ClassA {
    public void method() {assert false;} }

    class ClassB extends ClassA {
    public void method() {doSomething();} }

    ....

    ClassA thing = ...

    ...

    thing.method(); // only ever called if thing isKindOf ClassB

    Is this the best way in which to write this? Or is it better to leave the
    definition of method() out of ClassA, and rewrite the last statement above:

    ((ClassB) thing).method();

    If the program logic is wrong, in the former case the assertion will fail at
    runtime, while in the latter case the cast will fail at runtime.

    The latter method uses a cast, while the former method (necessarily) defines
    a method which will never be called. Which is the lesser evil? Or is there
    a better way still?

    In Smalltalk (where there is no casting), the convention is to write:

    ClassA>>method
    ^self subclassResponsibility

    where:

    Object>>subclassResponsibility
    ^self error: 'My subclass should have implemented this method'

    Cheers, Paul
     
    Paul Chapman, Feb 6, 2005
    #6
  7. Paul Chapman

    Paul Chapman Guest

    (My ISP is having trouble forwarding posts. Sorry for any delay.)

    > Any reason the methods aren't abstract ?


    Only one subclass is ever asked to run the method. If the base-class method
    was abstract, all the other subclasses would just have the same problem, and
    have to throw an exception to indicate a logic error in the program.

    Cheers, Paul
     
    Paul Chapman, Feb 6, 2005
    #7
  8. On Sun, 06 Feb 2005 00:19:00 +0000, Paul Chapman wrote:

    > (My ISP is having trouble forwarding posts. Sorry for any delay.)
    >
    >> Any reason the methods aren't abstract ?

    >
    > Only one subclass is ever asked to run the method. If the base-class method
    > was abstract, all the other subclasses would just have the same problem, and
    > have to throw an exception to indicate a logic error in the program.


    So, the base class, and all it's subclasses except for one have nothing to
    do with the method? In that case, why include it in the base class at all?
    It belongs into the subclass alone.

    --
    In pioneer days they used oxen for heavy pulling, and when one ox
    couldn't budge a log, they didn't try to grow a larger ox. We shouldn't
    be trying for bigger computers, but for more systems of computers.
    --- Rear Admiral Grace Murray Hopper
     
    Stefan Schulz, Feb 6, 2005
    #8
  9. Paul Chapman

    Paul Chapman Guest

    > So, the base class, and all it's subclasses except for one have nothing to
    > do with the method? In that case, why include it in the base class at all?
    > It belongs into the subclass alone.


    Because it is called on a variable declared as a reference to the base
    class, wich means the base clkass has to declare or define it.

    Can you suggest a better solution?

    Cheers, Paul
     
    Paul Chapman, Feb 6, 2005
    #9
  10. Paul Chapman

    Chris Smith Guest

    Paul Chapman <-online.co.uk> wrote:
    > > So, the base class, and all it's subclasses except for one have nothing to
    > > do with the method? In that case, why include it in the base class at all?
    > > It belongs into the subclass alone.

    >
    > Because it is called on a variable declared as a reference to the base
    > class, wich means the base clkass has to declare or define it.
    >
    > Can you suggest a better solution?


    We haven't seen (and don't want to see) enough code and requirements to
    decide... but it sounds very much like you might have some code that's
    out of place. If there's a method that's only declared in one subclass,
    then you shouldn't generally be calling it with a base class reference.
    Either you have thrown away information somewhere that you shouldn't
    have thrown away, or there is yet more code that *also* ought to be
    moved from its current location into the subclass.

    If circumstances have forced you to lose that information (i.e., to have
    a base class reference instead of a subclass reference), then you should
    cast it back again as soon as you re-learn this additional type
    information about the reference.

    --
    www.designacourse.com
    The Easiest Way To Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
     
    Chris Smith, Feb 6, 2005
    #10
  11. Paul Chapman

    Paul Chapman Guest

    > If circumstances have forced you to lose that information (i.e., to have
    > a base class reference instead of a subclass reference), then you should
    > cast it back again as soon as you re-learn this additional type
    > information about the reference.


    I asked about that solution in what now appears as the lowest post in this
    thread.

    Maybe I should indeed cast the reference and then onvoke the method.

    I agree with you that there's something strange in the problem itself, and
    that I should think again about how it arose, and how to redesign so that it
    never arises.

    Cheers, Paul
     
    Paul Chapman, Feb 6, 2005
    #11
  12. Paul Chapman wrote:

    > I wrote:
    >
    >
    >>I've just been rewriting some base-class methods which should never be
    >>called. ...

    >
    >
    > This made me think.
    >
    > abstract class ClassA {
    > public void method() {assert false;} }
    >
    > class ClassB extends ClassA {
    > public void method() {doSomething();} }
    >
    > ...
    >
    > ClassA thing = ...
    >
    > ...
    >
    > thing.method(); // only ever called if thing isKindOf ClassB
    >
    > Is this the best way in which to write this? Or is it better to leave the
    > definition of method() out of ClassA, and rewrite the last statement above:
    >
    > ((ClassB) thing).method();


    The best way to write it, if you _must_ declare "thing" as a reference
    to "ClassA", is as Chris Smith said, to cast it back as soon as you know
    its type again. If the scope of that knowledge is a single statement
    then you may have larger problems.

    There are other techniques for avoiding this sort of thing. The
    "Visitor" design pattern (a.k.a. "double dispatch") is all about
    providing for type-appropriate behavior when the specific type is
    unknown. We've already beaten it to death, but classes making use of
    composition instead of subclassing to provide such a behavior can also
    avoid this kind of problem.

    > If the program logic is wrong, in the former case the assertion will fail at
    > runtime, while in the latter case the cast will fail at runtime.
    >
    > The latter method uses a cast, while the former method (necessarily) defines
    > a method which will never be called. Which is the lesser evil? Or is there
    > a better way still?


    Better would be if the method doesn't exist on classes on which it
    shouldn't be invoked, and if no cast is necessary. Then you don't have
    to worry about either runtime failure. It is possible to achieve this
    (see above).

    >
    > In Smalltalk (where there is no casting), the convention is to write:
    >
    > ClassA>>method
    > ^self subclassResponsibility
    >
    > where:
    >
    > Object>>subclassResponsibility
    > ^self error: 'My subclass should have implemented this method'


    Which has the same problems (and at least some of the same solutions) as
    the Java version has, convention notwithstanding.

    --
    John Bollinger
     
    John C. Bollinger, Feb 7, 2005
    #12
  13. Paul Chapman

    Paul Chapman Guest

    John,

    > The best way to write it, if you _must_ declare "thing" as a reference
    > to "ClassA", is as Chris Smith said, to cast it back as soon as you know
    > its type again. If the scope of that knowledge is a single statement
    > then you may have larger problems.


    I have now done this.

    I've been trying to come up with a simple "real-world" example of where the
    problem might occur. Trouble is, the domain of my problem is OO itself,
    since I am building an ODBMS. OO is "strange", for example in that one
    might represent an "object" in a number of different ways, and that this
    representation might even change for a single object at runtime, say based
    on self-profiling and runtime re-optimisation (the kind of thing Self does).

    I haven't actually implemented any of this kind of re-optimisation yet,
    since I am at the prototyping stage. ("Get it working, stupid.") But I
    want to leave the door open, which has led to certain decisions about class
    structure, whence this particular (trivial) dichotomy has arisen.

    Thanks again for your help.

    Cheers, Paul
     
    Paul Chapman, Feb 7, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michal M
    Replies:
    7
    Views:
    797
    Andrew Thompson
    Aug 2, 2005
  2. Replies:
    3
    Views:
    5,181
    Bjorn Abelli
    Mar 30, 2006
  3. manzur
    Replies:
    5
    Views:
    501
    Chris Uppal
    Nov 9, 2006
  4. Alex Vinokur

    assert(x) and '#define ASSERT(x) assert(x)'

    Alex Vinokur, Nov 25, 2004, in forum: C Programming
    Replies:
    5
    Views:
    923
    Keith Thompson
    Nov 25, 2004
  5. lightning
    Replies:
    3
    Views:
    522
    Oliver Wong
    Apr 16, 2007
Loading...

Share This Page