a criticism of java

E

EricF

EricF sez:
.... I think if you examine your desktop computer closely,

I hear Sun has an entire desktop environment written in it.

Actually that's not true - but since they call it the Java Desktop System,
it's an easy mistake to make.

http://www.sun.com/software/javadesktopsystem/index.xml

I saw Gosling give a demo of it when it was running on Linux. It was pretty
cool. Now it runs on Solaris. I think it just a windowing system with some
bundled applications, some which very well may be written in Java.
....

Exceptions are a Good Thing(tm). Making exception part of method
signature -- not so much. You have to jump through hoops if you
want to just let it crash, you have to jump through hoops if you
want to overload on exception (e.g. read() method that throws
SQLException when backed by a DB, IOException when backed by flat
file, and no exception when backed by in-memory storage), etc.

Dima

If you don't want to deal with it - and that's legit - than catch it and throw
a runtime exception. It doesn't have to be part of the method signature.

try
{
...
}
catch (Exception e)
{
throw new RunTimeException(e);
}

Eric
 
R

ricky.clarkson

And, my beef was with certain methods throwing checked exceptions when
I felt they should've been throwing unchecked exceptions.

What do you base this feeling on?

Anyway, if you do think that the method should throw an unchecked
exception, wrap it.

public static void sleep(final int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (final InterruptedException exception)
{
throw new RuntimeException(exception);
}
}

I personally don't ever specify unchecked exceptions in throw clauses,
because that's code that has no effect.
I would not adapt the throws clause to provide documentation to a
checked exceptions that should really be unchecked.
Hence In those instances, I support not declaring them, by saying.
public int methodQ(String a) throws Exception
{

}

No, you are adapting the throws clause. If you say that you throw
Exception, then you are forcing the callers of your method to do the
same, or catch Exception. This is pointless.

Unless you actually do throw instances of Exception, not subclasses,
which itself would be pointless, you should declare to throw all
checked exceptions. If you don't want checked exceptions in your
signatures at all, then Exception is no better. Here's my usual
solution (really the previous one repeated):

public void doSomething()
{
try
{
code
}
catch (final IOException exception)
{
throw new RuntimeException(exception);
}
catch (final SQLException exception)
{
throw new RuntimeException(exception);
}
}

If you force people to catch Exception, you are forcing them to catch
RuntimeException too, which is usually not desired. I would ALWAYS
have separate catch blocks for each checked exception type, and a
separate one for RuntimeException. CheckStyle and findbugs have a
little to say on the matter, and can point out this error in your code:

http://findbugs.sourceforge.net/bugDescriptions.html#REC_CATCH_EXCEPTION
http://checkstyle.sourceforge.net/config_coding.html#IllegalCatch
I see your understanding is lucid. Are you a teacher?

Partly. I am a Research Assistant at the University of Salford, where
I work on Netsim ( www.netsim.info ) and tutor on a couple of modules.
I also lecture some A-Level students from a local college. My rushed
notes used for beginners in Java are available:

http://cime.net/~ricky/netsim/oldham/index.html

Primarily, I'm a programmer, so I learn from my own experience.
Do you recommend any particular book or sources of info for improving
my programming?

I found the idea of not duplicating code in comments in Bjarne
Stroustrup's C++ book, some years ago.

I just discuss ideas with other developers really, normally via IRC
(Freenode).
 
Q

q_q_anonymous

What do you base this feeling on?

by the way. thanks for the corrections which you made to many of the
things I suggested in the previous post.


a)Integer.parseInt was one of the method that got up my nose. It
throws a NumberFormatException - which is, checked.

b) BufferedReader br = new ..........FileReader(....)
that'll throw a FileNotFoundException (which is checked)
and
c) - related to b
br.read(...) <-- that'll throw an IOException (which si checked)


In the case of 'a' - integer.parseInt throwing the checked exception

Regarding the Integer.parseInt example. A method that returns a
boolean, could discern whether it is an integer.
Then one could call a method like Integer.parseInt which would throw an
IllegalArgumentException if it was passed a String that wasn't
representing an Integer .

String tbox="12345"
if(testint(tbox)) Integer.parseInt(tbox); else
System.out.println("Enter an integer");


Regarding FileReader throwing a FileNotFoundException. Again, I can
test if the file exists, and so, if I were to call FileReader, passing
it a file that didn't exist, then I would want an
IllegalArgumentException thrown. It's an error I could avoid and I
wouldn't write code to recover from it since it'd be programmer error.
Fine, in a multiuser application - many threads, some user may delete
the file after I verify that it exists. But since i'm writing a single
user / single thread, application, that sort of mischief isn't
expected, and I rightly don't want to check and recover from that. Let
thep program crash if the moment after I test for the file's existance,
the file disappears!.
If it were an unchecked exception, i'd have the choice to catch it if I
wanted to deal with it. But here - it beign a checked exception - I am
forced to catch it or declare it in the throws

Regardign c - br.read(..) . that I can understand, if it's a big
file, maybe the file will disappear. But still, I shouldn't be forced
to recover from that. Suppose I'm reading a small file, it'll take less
than 5 seconds to read. If the file suddenly disappears, then it's
blatant user negligence, and I don't want to code for that possibility,
I'm happy for the program to crash.


I think, your solution may be the only one. To catch the specific
checked Exceptions and throw a Runtime Exception (which is unchecked).
It's still longwinded though. And those methods I mention are quite
common.

I guess that since they are common, one could rewrite versions of those
methods that don't throw checked exceptions.



Anyway, if you do think that the method should throw an unchecked
exception, wrap it.

public static void sleep(final int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (final InterruptedException exception)
{
throw new RuntimeException(exception);
}
}

I personally don't ever specify unchecked exceptions in throw clauses,
because that's code that has no effect.




No, you are adapting the throws clause. If you say that you throw
Exception, then you are forcing the callers of your method to do the
same, or catch Exception. This is pointless.

yeah, it was silly. That all encompassing Exception was of course a
Checked Exception.

Unless you actually do throw instances of Exception, not subclasses,
which itself would be pointless, you should declare to throw all
checked exceptions. If you don't want checked exceptions in your
signatures at all, then Exception is no better. Here's my usual
solution (really the previous one repeated):

public void doSomething()
{
try
{
code
}
catch (final IOException exception)
{
throw new RuntimeException(exception);
}
catch (final SQLException exception)
{
throw new RuntimeException(exception);
}
}

If you force people to catch Exception, you are forcing them to catch
RuntimeException too, which is usually not desired. I would ALWAYS
have separate catch blocks for each checked exception type, and a
separate one for RuntimeException. CheckStyle and findbugs have a
little to say on the matter, and can point out this error in your code:

http://findbugs.sourceforge.net/bugDescriptions.html#REC_CATCH_EXCEPTION
http://checkstyle.sourceforge.net/config_coding.html#IllegalCatch

yikes, so, I won't be doing that catch exception adn throws exception!

How about this, which rethrows unchecked exceptions like NPEs and IAE

try
{

/* code with Integr.parseInt, FileReader, .read(..) */

}
catch(Exception e)
{
/*
Have a method that tests the Exception, if it is an
IOException or a
FileNotFoundException, then the method will catch it -
swallowing it.
Otherwise, it's some other exception, like a unchecked IAE
or NPE.
So it'll throw that Exception back out.
*/

}
 
R

ricky.clarkson

a)Integer.parseInt was one of the method that got up my nose. It
throws a NumberFormatException - which is, checked.

The problem with the test-first strategy is that you are duplicating
effort. Nearly all the effort required to parse an int is required to
verify an int.

See the recent thread on "Using exceptions for early exit" in
comp.lang.java.programmer for my suggestions (and some
counter-arguments) on alternative ways of doing this.
But since i'm writing a single
user / single thread, application, that sort of mischief isn't
expected

I would never trust a user (even/especially myself) not to delete a
file under my nose. If you can trust a user, then you are dealing with
a VERY VERY rare case. Most users do mischevious things if they can.

By the way, FileReader is worth avoiding because you can't set its
encoding. It uses the default platform encoding (unless you change
that). It's better to use InputStreamReader, I think.
Regardign c - br.read(..) . that I can understand, if it's a big
file, maybe the file will disappear.

I don't think a file can be deleted if you're reading from it, but that
might be OS-dependent. However, a filesystem might disappear,
especially a remote one.

Also, you might close the FileReader before the BufferedReader, so the
BufferedReader has to throw an IOException in that case.

The problem with using this construct:

try
{
code
}
catch (final Exception exception)
{
if (exception instanceof RuntimeException)
throw (RuntimeException(exception;

logger.log(exception);
}

is that it is not explicit. You might think that you're handling an
IOException and a NumberFormatException with it, then you might add
some code that does an SQL query. It will silently start catching
SQLException, and just logging it. It would be better to have to deal
with SQLException, so that you can, e.g., close the database Connection
and System.exit(1); or whatever you want to do in the case of an
SQLException.

Being explicit is good for avoiding bugs, but not good for stopping you
from having to type a lot. I don't mind typing a lot (if you haven't
noticed). I do mind hunting bugs.
 

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,271
Latest member
BuyAtenaLabsCBD

Latest Threads

Top