tags:

views:

763

answers:

9

The same as this question but for java

Update Based on the comments and responses of a few people, Its clear that Java has very little undefined behaviour.

So I'd like to ask as well what behaviour is not obvious. Please when answering make the disticnction between the two :)

+7  A: 

Anything to do with threads... :)

Also:

  • Overriding methods and expecting them to be used in the same way between versions
  • Assumptions about underlying platform (file separator, for instance)
  • Details of garbage collection/finalisation
  • Some details about class initialisation
  • Whether Integer.valueOf (and the like) return the same objects
  • Performance, latency and memory usage
Tom Hawtin - tackline
I wouldn't say "anything" but definitely the exact timing and scheduling.
Joachim Sauer
Garbage collection/finalization is a very good point!
Joachim Sauer
A lot of these items while are undefined, shouldn't ever be defined. And then there are others that are pitfalls and not undefined.
Pyrolistical
+3  A: 

Well defined but not obvious:

Object test for equality:

== is used to test references ( do these two object references point to the same object )

While equals is used to test object equality.

So for instance

new String("test") == new String("test")

Is false, while

new String("test").equals( new String("test") )

Is true

String objects are interned so the following returns true:

String a = "test";
String b = "test;

a == b  // returns true

BUT if the string is created somewhere else ( from a database for instance )

String a = "test";
String b = getFromDataBase(); // internally the remote returns "test"

a == b  // returns false.

The validation is false.

I've seen this happening in jsp with scriplets, and new programmers don't get why the validation

 <%if( param == "continue" ) { %>

Never happens

OscarRyz
Nope, this is not "undefined".This is actually well defined, just a pitfall.
Pyrolistical
Well, whether a particular API returns an interned String or not is undefined.
Tom Hawtin - tackline
That first sentence should read "but not obvious" - you're missing a "T"
Bob Cross
String *literals* are interned, not String objects. A non-literal String object may be interned with the intern() method.
Jason Day
A: 

The one thing I remember is regarding jvm compatibility with jni. We had and application that was developed on jdk1.4 and when installing it on a machine with ibm jvm (jikes I believe), the jni call just puked! That was in 2006 though. I believe this has little to do with java as a language, but more to do with java as a platform.

questzen
+5  A: 

There is very, very little undefined behavior in Java, when compared to C/C++, it is a much more well-defined platform. The reason for this is that C/C++ compilers are meant to produce code for very different platforms and therefore were granted rather wide freedoms in order to prevent too stringent requirements that would force a compiler to produce suboptimal code for a given platform.

Java sacrificed some of that by defining almost every behavior in a very exact way and allowing only small degrees of freedom. This of course makes the platform somewhat easier to handle.

The main area where undefined behavior happens is the exact timing and scheduling of multiple threads (as Tom Hawtin already mentioned)..

There are several places where the behavior is not obvious, 'though, so it might look undefined, but isn't (the String comparison examples given by Oscar Reyes are a great example).

And a few places where the behavior is defined to be undefined (for example the order of elements in a HashMap is defined to be implementation dependent and needs not be constant).

Joachim Sauer
Ya, but exact timings shouldn't be defined. So its meaningless to point out they ain't...
Pyrolistical
Pyro: probably, but some developers expect a newly started thread to always be scheduled before the thread calling Thread.start() and that isn't defined one way or another. That's the kind of timing details that I meant.
Joachim Sauer
+2  A: 

I am not entirely sure what you mean by "undefined behaviors", but as others have pointed out, the core language is very predictable across platforms, and versions of the language and JVM.

This is not true for graphics (Swing, AWT), however, which tend to be unpredictable and not necessarily reproducible across different platforms. I worked on a graphics intensive Java based visualization application and I spent a lot of time "writing once, and debugging everywhere".

Also, Object.clone() has some major problems, and its use is discouraged in most cases. Please see Item 11, from "Effective Java" by Joshua Bloch for a complete answer.

Julien Chastang
+3  A: 

Serialization. It's not undefined, per se (there is a deterministic algorithm). However, it is not at all obvious to the casual observer what will or will not cause a change in the serialVersionUID, thus foiling all your attempts to make use of RMI, JMS and a variety of other acronyms.

So, it is usually a good idea to consider your options when you know that you will need to serialize an object. I'm particularly fond of "always include it as a field" technique:

private static final long serialVersionUID = 1L;

Only change the value of that field when you, the developer know that there has been a compatibility-killing change to your code. Don't let the JDK make that decision for you....

Bob Cross
A: 

Add dynamic vs. static binding and how it is applied against overloaded and overridden methods as not obvious.

Robin
+4  A: 

I think that Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases book will be very useful, it explains many hidden points and undefined behaviours of java.

Was going to mention this myself. It's the definitive source for odd and unexpected behaviour.
GaryF
A: 

Not undefined but an unexpected behavior is how doubles are rounded when converted to an integer. 0.6d always rounds down to 0; actually 0.9d also rounds down to 0. But 0.99999999999999995 and greater will round up to 1.

Just an interesting behavior when casting the results of a Math.random() call to beaware of.

shrub34