Java language and library suggestions

A

Arne Vajhøj

Tomas said:
And this is the case I want the program to crash. It is reading the
configuration during initialization and the configuration contains
invalid value. I get an error, fix the configuration and run again.

But you do not get the exception you should.

You get an assertion error.
And if you don't want your program to crash in this situation, noone
forces you to use this construct.

No. But little point in adding features to the language that
are not really needed just because people do not need to use
them.
No, not the same benefits. It has its own benefits.

Let me rephrase: it does not carry benefits in the same order
of magnitude as exceptions and checked exceptions.
But the talk here
is about misuse, not benefits. And misused @Safe would usually do less
damage than misused try-catch.

You have to compare benefits with with drawbacks.
I can't object, but compare it to construct that it is meant to
replace, i.e.
try {
safe_statement;
} catch(EXCEPTION e) {
throw new AssertionError(e); // or throw new RuntimeException(e);
}

How is misuse of @Safe more difficult to find than the misuse of this?

It is more difficult to spot.

And besides the construct itself is not very good in the first place.

Arne
 
T

Tomas Mikula

I don't think "the declaration of the argument is probably just
a few lines above" is a good argument in software development.

Substitute 1-10 for "a few" and omit "probably" and it is a good
argument for me.
Consider the example:
int i=8;
double d=1;
String s=null;
// now the following code is necessary, because I don't want to rely
// on the assumption that i==8
if(i!=8){
// handle the exceptional state when i!=8
}
No no.

He is not changing anything.

He gave you an API where he said that he might throw an
exception.

And he also said (in the documentation) that he won't throw any other
exception than that thrown from the provided Writer.
You decided to code against his implementation instead
of the API he gave you.

He changed the implementation without changing the API.

Your code broke.

You violated the rules of encapsulation.

He was doing good OOP.


Maybe not. But in this case the API actually provides the
information that it may throw an exception.

The fact that some information may be missing is not a good
argument to ignore the information provided.


In this case the JDBC specification says that the implementation
must do that, so that it is not up to the implementer whether
what he does.

It can still be argued that it is good to do it explicit,
because the implementation may have an error.

It would still be an error in the implementation, but
defensive programming is good.


No, but it has to return the length. Length can not be negative.

So a correct implementation will always return an int >= 0.

Math.abs(int) has to return the absolute value. Absolute value cannot
be negative.
One would think that a correct implementation will always return an
int >= 0.
Yet it returns negative value for Integer.MIN_VALUE.

If Math.abs() can return negative value, so could String.length(). But
if the documentation of String.length() says it won't return negative
value, I will trust it, as well as I will trust the documentation of
WriterEncoder.writeEncoded() that it won't throw any IOException other
than propagated from the provided Writer.
It does.


1) That does not make it good.

Nor bad.
2) And it is hopefully very rare that such blatant violations of
    OOP encapsulation are done

It's not a violation fo encapsulation. It's relying on the specified
semantics.

Tomas
 
A

Arne Vajhøj

Tomas said:
Substitute 1-10 for "a few" and omit "probably" and it is a good
argument for me.
Consider the example:
int i=8;
double d=1;
String s=null;
// now the following code is necessary, because I don't want to rely
// on the assumption that i==8
if(i!=8){
// handle the exceptional state when i!=8
}

If the logic you are implementing has a special case for
i!=8, then you most certainly should put the code
there.

The decision was made that i was a plain int and not
a final static int.

It seems obvious to me that you should implement
the complete logic of whatever you are coding.
And he also said (in the documentation) that he won't throw any other
exception than that thrown from the provided Writer.

Java Doc usually documents current implementation.

You should not consider it binding for the future.

(at least not unless it is very controlled code)
Math.abs(int) has to return the absolute value. Absolute value cannot
be negative.
One would think that a correct implementation will always return an
int >= 0.
Yet it returns negative value for Integer.MIN_VALUE.

If Math.abs() can return negative value, so could String.length().

Nonsense.

The fact Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE (for
obvious reasons) does not by magic invent strings of negative
length.
> But
if the documentation of String.length() says it won't return negative
value, I will trust it, as well as I will trust the documentation of
WriterEncoder.writeEncoded() that it won't throw any IOException other
than propagated from the provided Writer.


Nor bad.

No it is bad because of the risk of producing unexpected
behavior later.
It's not a violation fo encapsulation. It's relying on the specified
semantics.

The only enforced semantics is the fact that the code clearly
states that it may throw an exception.

Arne
 
T

Tomas Mikula

But you do not get the exception you should.

You get an assertion error.

With a stack trace which is enough for these purposes. And as others
have suggested, It could be a better idea to throw RuntimeException
insted of AssertionError and then you get your exception, just
wrapped.
No. But little point in adding features to the language that
are not really needed just because people do not need to use
them.

There are many things you don't necessarily need to use. But it's
advantageous to use them.
Okay, you don't see any benefit in using @Safe. Noted. Others may.
Let me rephrase: it does not carry benefits in the same order
of magnitude as exceptions and checked exceptions.

I like checked exceptions. Proposed construct is not meant to replace
them. It's meant to supplement them. Then comparing its benefits to
the benefits of checked exceptions is like comparing the benefits of
finally clause to benefits of try-catch.
You have to compare benefits with with drawbacks.

Then @Safe clearly wins for me.
It is more difficult to spot.

It is easier to spot and easier to analyze, because you don't need to
read the catch block.
And besides the construct itself is not very good in the first place.

In some cases it is good. And @Safe would be good in these same cases,
plus it would be more readable.

Tomas
 
T

Tomas Mikula

If the logic you are implementing has a special case for
i!=8, then you most certainly should put the code
there.

But right after that I need to check that d is still 1 and s is still
null. But I have already written too many lines since I last checked
that i==8, so I need to check this again...
The decision was made that i was a plain int and not
a final static int.

Yes because that int will be changing somewhere down the code.
It seems obvious to me that you should implement
the complete logic of whatever you are coding.





Java Doc usually documents current implementation.

You should not consider it binding for the future.

(at least not unless it is very controlled code)






Nonsense.

The fact Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE (for
obvious reasons) does not by magic invent strings of negative
length.

There might be some "obvious" reason for length() to return negative
value for some corner case. You just don't find it obvious for the
first time.
(By some lucky coincidence there is no corner case for String.length
().)
 >                                                                 But



No it is bad because of the risk of producing unexpected
behavior later.



The only enforced semantics is the fact that the code clearly
states that it may throw an exception.

We already talked about this. I'm going to repeat that the only
enforced semantics of String.length() is that it returns int.

Tomas
 
L

Lew

Nonsense.

The fact Math.abs(Integer.MIN_VALUE) returns Integer.MIN_VALUE (for
obvious reasons) does not by magic invent strings of negative
length.

Tomas presents a straw man anyway. One would most assuredly not think a
correct implementation of java.lang.Math.abs() would always return an int >=0
were one to read its documentation. One would expect a correct implementation
to perform in accordance with the documentation. As indeed they do.

<http://java.sun.com/javase/6/docs/api/java/lang/Math.html#abs(int)>

While we're at it:
<http://java.sun.com/javase/6/docs/api/java/lang/String.html#length()>
 
T

Tom Anderson

Have we been reading completely different threads? The whole point of this is
for situations where the exception *is* impossible. Or perhaps you could
explain to me how this line:

Reader r = new InputStreamReader(System.in, "UTF-8");

Is capable of throwing an IOException.

By which of course i mean an UnsupportedEncodingException. My apologies.

tom
 
T

Tom Anderson

No.

It relies on:
1) that it is indeed a StringWriter and not another writer that gets
passed in as argument
2) that writeEncoded only throws IOException if the passed Writer
throws IOException.

Bad code.

Every, *every*, line of code you write relies on the lines of code right
before it. That's how code works. Your argument is utterly specious.
No it does not.

WriterEncoder.writeEncoded's API specifies that it throw IOException. It
does not say anything about when it does it.

Flat out wrong. From the code above:

/** @throws IOException if and only if the write() methods of underlying Writer throw an exception. */

Anyway, i don't think there's any point in us arguing about this any more,
because we're clearly living in different universes. Have a good week!

tom
 
T

Tomas Mikula

Tomas presents a straw man anyway.  One would most assuredly not think a
correct implementation of java.lang.Math.abs() would always return an int >=0
were one to read its documentation.  One would expect a correct implementation
to perform in accordance with the documentation.  As indeed they do.

Exactly. And that was my point. One would expect a correct
implementation of WriterEncoder to perform in accordance with the
documentation.

Tomas
 
M

Markus Eberle

Arne said:
No.

It calls an API that declares to throw an IOException.

Maybe it is not possible in current implementation.

But it may be possible in 5 or 10 years.

Which is why that it is good to program to the contract
and not to ones knowledge about the implementation.

But the allowed parameters are part of the contract.
As already said: If the Javadoc states that an exception is thrown when
condition XYZ is (not) met, then it is part of the contract.

If my code now ensures that this condition does not happen, then it
would be fine to use the "@safe" construct to indicate:
"I know there might be an Exception, but i know what i am doing"

Cheers,
Markus
 
T

Tomas Mikula

4. Sometimes having to catch an exception that will never be thrown is
really annoying.
For example, I would like to write something like

@safe
URI uri = new URI("http://valid.uri.com/");

instead of

URI uri;
try {
uri = new URI("http://valid.uri.com/");
} catch(URISyntaxException e) {
throw new AssertionError(e);
}

I used the annotation notation, but I doubt something like this can be
achieved with annotations. It would be nice if the language had a
construct to mark some code exception safe and if it threw an exception,
it would result in AssertionError. It could also be more flexible, like
this

@safe(NumberFormatException, UnsupportedEncodingException) {
// statement that should not throw any NumberFormatException or
UnsupportedEncodingException
// and if it does, it is an AssertionError
}

I've just found out that something similar (not quite the same) is
possible with the @SneakyThrows annotation on a method:
http://projectlombok.org/features/SneakyThrows.html
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top