[jdk1.5.0_01] assert false

P

Paul Chapman

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
 
A

Andy Hill

Paul Chapman said:
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?
 
J

Jim

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
 
D

dolapo

Jim said:
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 ?
 
P

Paul Chapman

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
 
P

Paul Chapman

I said:
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
 
P

Paul Chapman

(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
 
S

Stefan Schulz

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


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.
 
P

Paul Chapman

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
 
C

Chris Smith

Paul Chapman said:
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
 
P

Paul Chapman

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
 
J

John C. Bollinger

Paul said:
I wrote:




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.
 
P

Paul Chapman

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top