switch using strings

  • Thread starter Dirk Bruere at NeoPax
  • Start date
L

Lew

What's the danger? "Danger" in this context suggest strange, unexpected,
or "undefined" behavior is possible, or that it invites thread-safety or
exception-safety errors, or is likely to cause cryptic and difficult to
debug problems. NPEs arising from dereferencing null references is
nothing at all strange or surprising though.

There is nothing about "strange" or "surprising" in the definition of
"danger", just risk of harm. NPE is harm. Misuse of autoboxing can
cause that harm. Ergo, autoboxing is dangerous.

http://www.merriam-webster.com/dictionary/danger?show=0&t=1299099462

As you well know, but that would interfere with your desire to be
argumentative.

So based on your behavior,
http://lmgtfy.com/?q="shut+the+front+door"

I'm done with you.
 
P

Paul Cager

Spooky. If you type in:
     +lew autoboxing dangerous
to Google search you get:
     http://www.javakb.com/Uwe/Forum.aspx/java-programmer/[snip]
Some would say that's just a coincidence. Personally I think it is a
sure sign that there are Dark and Mysterious Forces at work here.

Nah, it's just that some web sites are archiving/mirroring this
newsgroup, and in particular this thread.

While that's certainly true, I don't think it is relevant. The link I
gave was to a thread over 3 years old:

http://www.javakb.com/Uwe/Forum.aspx/java-programmer/36707/Java-7-features

Maybe the Dark and Mysterious Forces are also time travellers.
 
T

Tom Anderson

There you go, one of the dangers of autoboxing. Congratulations, you
got it.

I don't understand why this is dangerous. Without autoboxing, you'd write:

public int jill = bill.intValue();

Which has exactly the same behaviour.

Are you thinking that the autoboxing hides the fact that there's an
object-to-primitive conversion (well, a method call, in fact), and so
conceals the possibility of the NullPointerException? That seems like a
fairly minimal kind of risk to me.

Or perhaps there's a misunderstanding of your original statement here. You
said that the proposed diamond operator was "about as helpful as
autoboxing [...] and perhaps as dangerous"; perhaps you think it will be
handy and safe?

tom
 
T

Tom Anderson

My favourite: what is printed by the following class?

import java.util.ArrayList;
import java.util.List;

public class Test1 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();

// What is printed?

list.add(Integer.valueOf(42));
list.remove(Integer.valueOf(42));
System.out.println(list.size());

list.add(42);
list.remove(42);
System.out.println(list.size());
}
}

My prediction is that the list is empty both times.

*compiles*

*runs*

Ha! Good one. You got me fair and square.

Those methods should not both have been called that. That's very much a
problem with API design, not autoboxing. :)

tom
 
J

javax.swing.JSnarker

There is nothing about "strange" or "surprising" in the definition of
"danger", just risk of harm. NPE is harm.

By your definition of "danger", then, the existence of "null" in Java is
itself bad and dangerous and it should be eschewed.
Misuse of autoboxing can cause that harm. Ergo, autoboxing is dangerous.

By your definition of "danger", then, any Turing-complete programming
language is "dangerous", since if it can do anything nontrivial at all
it can "cause harm" if the programmer makes a mistake.
As you well know, but that would interfere with your desire to be
argumentative.

Pot, kettle ...

--
 
L

Lew

There you go, one of the dangers of autoboxing. Congratulations, you got it.

I don't understand why this is dangerous. Without autoboxing, you'd write:

public int jill = bill.intValue();

Which has exactly the same behaviour.

Are you thinking that the autoboxing hides the fact that there's an
object-to-primitive conversion (well, a method call, in fact), and so conceals
the possibility of the NullPointerException? That seems like a fairly minimal
kind of risk to me.

Or perhaps there's a misunderstanding of your original statement here. You
said that the proposed diamond operator was "about as helpful as autoboxing
[...] and perhaps as dangerous"; perhaps you think it will be handy and safe?

Autoboxing hides the method call so people tend to forget the risk unless
they're careful.

Autoboxing is relatively useless. Taking our example, it saves eleven whole
characters of typing. Wow!

There are other risks, as shown in the google links from the query I posted.

You can read them if you care to educate yourself.

Did I say the risks were gigantic anywhere? I said they exist. I've proven
that. Now folks are shifting the argument to, "Well, yeah, they exist, but
they aren't large." Okay, they aren't large.

But people in this very forum have posted questions about why their vararg
method that took Integer [] arguments acted weird when passed a series of int
arguments. (Or is it the other way around? GIYF there.) Obviously the risk
is real enough that people actually run afoul of it.

Facts are facts. You can win the rhetorical argument, in fact, I'll concede
it. You've won the rhetorical argument. Congratulations. Winner! You're a
Vatican assassin!

But reality will remain real despite your rhetorical victory.

Go study the facts for yourself. You don't need me for that.

http://lmgtfy.com/?q=java+dangers+of+autoboxing
 
E

Eric Sosman

What so-called "diamond operator"?


Since when is autoboxing "dangerous"?

Not so long ago, somebody asked for help here with an "obviously
correct" construct that wasn't working right. Paraphrasing:

public class Paraphrase {
private Integer counter = 0;
public void increment() {
synchronized(counter) {
++counter;
}
}
}

It's my belief that if there were no such thing as autoboxing, he
would never have made this mistake in the first place -- hence,
autoboxing contributed to the mistake, and is therefore dangerous
to at least some degree.
 
E

Eric Sosman

[... "autoboxing is dangerous" ...]

It's not a personal opinion, it's a fact, and it is googlable. Stop
trolling and start researching.

"Dangerous" is a judgment, an assessment, a matter of opinion
and not a "fact."

Also, if you Google even a little bit you can probably find a
site that espouses any folly you care to name. For example,

"[...] the earth is a flat disk centered at the North Pole
and bounded along its southern edge by a wall of ice, with
the sun, moon, planets, and stars only a few hundred miles
above the surface of the earth."

(You want a citation? GIYF; GIFY.)
 
J

javax.swing.JSnarker

Not so long ago, somebody asked for help here with an "obviously
correct" construct that wasn't working right. Paraphrasing:

public class Paraphrase {
private Integer counter = 0;
public void increment() {
synchronized(counter) {
++counter;
}
}
}

IMO, if this does *not*:

* start counter as an Integer whose value is 0
* lock it before each increment
* unbox it, add one, box it again, and reassign
* and then release the monitor

then that's actually a language bug, or at least a wart. "++x" is
supposed to be equivalent to "x = x + 1"; here, "x + 1" would require
unboxing and "x = ..." would then require boxing again. What does it do
instead, increment the temporary but fail to reassign? Refuse to compile
++<reference> in general?

It seems whatever the exact problem was it could have been avoided by
making a different choice in the implementation of some aspect of the
language.

--
 
E

Eric Sosman

IMO, if this does *not*:

* start counter as an Integer whose value is 0
* lock it before each increment
* unbox it, add one, box it again, and reassign
* and then release the monitor

That is precisely what it does. See the bug yet?
then that's actually a language bug, or at least a wart.

Yes, IMHO, even though it behaves exactly as you describe.
"++x" is
supposed to be equivalent to "x = x + 1";

It is.
here, "x + 1" would require
unboxing and "x = ..." would then require boxing again.
Yes.

What does it do
instead, increment the temporary but fail to reassign?
No.

Refuse to compile
++<reference> in general?

Still no.

Re-write the code without auto-boxing/unboxing -- pretend you're
using a pre-1.5 Java -- and I'm sure you'll see the problem. (And
since you didn't see it right away, I think that lends support to the
notion that autoboxing is, or at any rate can be, "dangerous.")
It seems whatever the exact problem was it could have been avoided by
making a different choice in the implementation of some aspect of the
language.

Agreed. For example, choosing not to have autoboxing.
 
J

javax.swing.JSnarker

Agreed. For example, choosing not to have autoboxing.

Well, it looks like the problem is that the lock isn't on a consistent
object. Of course, making the whole method synchronized fixes it if
there are no other synchronized methods in the class, or other things
synching on its instances.

Ultimately, the problem lies with autoboxing using the immutable
Integer, etc. classes and not mutable versions of these, or else with
the way locking itself works. It probably couldn't easily be fixed in a
backwards-compatible way, unfortunately.

I must wonder why whoever wrote that code didn't just use AtomicInteger...

--
 
E

Eric Sosman

Well, it looks like the problem is that the lock isn't on a consistent
object. Of course, making the whole method synchronized fixes it if
there are no other synchronized methods in the class, or other things
synching on its instances.

Bingo! Well, the phraseology is a little strange: Since the lock
is on one object, period, it's on a "consistent object." However, there
are two objects in play (three, counting the Paraphrase instance), and
the locked object turns out not to be the right one.
Ultimately, the problem lies with autoboxing using the immutable
Integer, etc. classes and not mutable versions of these, or else with
the way locking itself works. It probably couldn't easily be fixed in a
backwards-compatible way, unfortunately.

Pre-1.5, the programmer would have written

private Integer count = Integer.valueOf(0);
void increment() {
synchronized(count) {
count = Integer.valueOf(count.intValue() + 1);

.... and right about here would quite likely have said "Oh, wait..."
That's why I believe autoboxing contributed to the bug.
I must wonder why whoever wrote that code didn't just use AtomicInteger...

.... for which there's no autoboxing. The prosecution rests.
 
L

Lew

[... "autoboxing is dangerous" ...]

It's not a personal opinion, it's a fact, and it is googlable. Stop
trolling and start researching.

"Dangerous" is a judgment, an assessment, a matter of opinion
and not a "fact."

Also, if you Google even a little bit you can probably find a
site that espouses any folly you care to name. For example,

"[...] the earth is a flat disk centered at the North Pole
and bounded along its southern edge by a wall of ice, with
the sun, moon, planets, and stars only a few hundred miles
above the surface of the earth."

(You want a citation? GIYF; GIFY.)

"Dangerous" is an objective representation of the presence of harmful
possibilities, using commonly accepted notions of harm.

You can choose your own judgment, of course. I've presented the facts. The
Google query I proposed was crafted to show several links from the first page
that provided relevant information. I looked at several of them. I walked
the walk and followed the links I suggested.

They showed me that there is a body of "opinion", as you call it, and evidence
for actual situations, some of which we've heard about in this very newsgroup,
where improper or naive use of auto(un)boxing caused surprising and
problematic behavior.

Suppose I grant that "dangerous" is an opinion. It is a fact that
practitioners have experienced undesired outcomes through ignorance of
autoboxing's behaviors.

Now, instead of piling on me like a rugby scrum, folks, consider if I'm asking
people to do something prudent or foolish. "Be careful, autoboxing is
dangerous." That communicates advice to research (why should I suddenly be
Professor Proof for all you lazy jerks?) and *decide for yourself* what the
limits of autoboxing are so that you are not surprised.

And people call me a nitpicker. You're all just a pack of cards.

Suppose you win. No one checks the limits of what autoboxing does. They get
bugs. It's actually happened. Let it continue. Winner! Vatican assassin!

No wonder there's so much buggy code out there.
 
L

Lew

Eric said:
Re-write the code without auto-boxing/unboxing -- pretend you're
using a pre-1.5 Java -- and I'm sure you'll see the problem. (And
since you didn't see it right away, I think that lends support to the
notion that autoboxing is, or at any rate can be, "dangerous.")

That's just your opinion.

:)
 
J

javax.swing.JSnarker

"Dangerous" is an objective representation of the presence of harmful
possibilities, using commonly accepted notions of harm.

By that criterion, just about everything is "dangerous".

In practice, though nothing is ever truly, 100%, absolutely perfectly
safe, a line tends to be drawn somewhere where the frequency or
likelihood or severity of harm is below some threshold and considered to
divide "safe" from "dangerous".

Where that line gets drawn *is* a matter of opinion, and indeed it can
vary quite a bit from person to person.
Suppose I grant that "dangerous" is an opinion. It is a fact that
practitioners have experienced undesired outcomes through ignorance of
autoboxing's behaviors.

The cure for ignorance is knowledge, not a crusade to stamp out whatever
was slightly complex enough that some people were capable of being
surprised by it.
Now, instead of piling on me like a rugby scrum, folks

Well, this is interesting. This newsgroup has a history of "piling on
people like a rugby scrum" over differences of opinion on arcane
matters, but usually you've been on the dishing-out end of it. Most
recently vs. Wesson, and in the past vs. Green, Gerrone, and others. Now
you're finding out how the other side likes it. ;)
consider if I'm asking people to do something prudent or foolish.
"Be careful, autoboxing is dangerous."

You didn't seem to be asking people to be careful with autoboxing; you
seemed to be asking people never to use it, and suggesting that Java
should stop changing, too. (One wonders if it's because you've got a lot
of time and effort invested in having memorized the JLS, and if they
change something again you'll have to memorize it all all over again. ;))
That communicates advice to research (why should I suddenly be
Professor Proof for all you lazy jerks?)

It seems you have been self-appointed to that role for years now, Lew.
(Perhaps something to do with whatever makes you view the entire rest of
the population of the planet as "you lazy jerks"...)
And people call me a nitpicker. You're all just a pack of cards.

After taking careful measurements of my dimensions and using a mirror to
examine my own surface for printed numerals, hearts, diamonds, and so
forth, I am forced to conclude that that assertion of yours is erroneous.

On further consideration, even a weakened "some of you are packs of
cards" seems improbable, though I cannot quite disprove that version.
Suppose you win. No one checks the limits of what autoboxing does. They
get bugs. It's actually happened. Let it continue. Winner! Vatican
assassin!

You've uttered this non sequitur three times recently. Some unusual
Tourettes-like tic, perhaps?
No wonder there's so much buggy code out there.

And all this time I thought that was mostly down to C's lack of bounds
checking, C's lack of decent libraries so everyone's always reinventing
the square wheel when they need hash maps and growable lists, and
Microsoft. :)

--
 
L

Lew

Peter said:
The problem is that each time the variable "counter" is reassigned, you get a
new object. In other words, as soon as it gets reassigned, you're dealing with
a whole new monitor for the purpose of the "synchronized" statement.

So, thread 1 acquires the lock, thread 2 waits for the lock, thread 1 updates
the counter, thread 3 calls increment(): bang! Thread 2 and thread 3 now are
both executing the code inside the supposedly "synchronized" block in the
increment() method.

Personally I find Lew's opinion on the matter to be over-stated. Yes, there's

Depends on how much you think I stated. All I said was that I don't find it
useful (it only saves a few characters of typing), and that it's dangerous on
the evidence. And that consequently I prefer not to use it.

Wow. Strong stuff. Better rein it in, huh?
a hazard. But in reality, there are _lots_ of hazards related to concurrent
programming; auto-boxing offers other conveniences that outweigh whatever
minor concerns its presence creates in the concurrent APIs.

(And frankly, the supposed null reference scenario mentioned earlier is
silly…as pointed out, that's simply a programmer error that could just as
easily occur without auto-boxing; the problem will show up the first time
someone tries to run the code, and is not difficult to figure out and fix).

But opinions vary, obviously. :)

You are absolutely correct. The example was trivial, not tied to autoboxing
particularly, and perfectly scaled for someone who was apparently unwilling to
do the research.

And certainly started a conversation that led to all sorts of useful links,
concrete and much, much better examples than mine, and hours of entertainment.
Oh, and utter vindication of my original, overstated point:

Autoboxing isn't all that useful. It has dangers. I prefer not to use it.

HTH.
 
J

javax.swing.JSnarker

It does, and yes…if those assumptions are valid, it can address the
problem even without interfering with other code. But so what? It
doesn't change the fact that there's a way to write the code such that
it _looks_ correct, but which actually is not.

That's always going to be possible in any nontrivial programming language.

It might be useful if the compiler emitted a warning when synchronizing
on a non-final instance variable.
Since Java also doesn't have operator overloading for classes, even if
Integer were mutable (which would be a really bad idea in and of itself)

You'd have to use a new, mutable Integer-like class instead of Integer
itself, obviously.
the use of the ++ operator would result in auto-boxing and a new object
instance anyway.

+ is overloaded for java.lang.String. That Java does not permit the
*user* to add operator overloads does not mean the *language designers*
cannot do so.
Or an "int" instead of an "Integer".

You can't synchronize on an "int".
I may disagree with Lew (and perhaps others) on the degree to which the
presence of this particular "gotcha" argues against auto-boxing as a
feature generally. But it _is_ a very real "gotcha"

Yes, it would seem that way. Of course, concurrency in general tends to
be one single giant "gotcha" much of the time anyway. :)


--
 

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,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top