The Java language is gradually changing from the initial network/apple language and into modern systems development. Here's a list of some of the resent changes and upcoming proposals.
The thing that I don't like are those changes which are only there to save keypresses... Autoboxing for example, is a dreadful thing, and (imho) should never have been added...
I get the feeling some things are added for marketing purposes, and not to suit the needs of the development community at large... And others are added as they are hyped up and shouted about until they seem "important"
As the saying goes "The squeaky wheel gets the grease"
Maybe it's time the majority of developers stood up and said what they wanted, rather than letting java mutate with all these new facilities just because they are "cool"?
Or maybe I'm in the minority, and should just shut up ;-) hee hee
Oh, I like autoboxing. I think it could have been done infinitely better, but it does simplify code in a lot of places. Unfortunately, it can also make certain algorithms devilishly confusing. *shrugs*
I do admit that I like the new scripting engine, and I really like the idea of operator overloading - as long as it's done better than C++. Personally, I really like Ruby's operator overloading implementation, though I don't know how practical that sort of impl would be for Java because of Java's inherant syntactical limitations. However, properties, closures, and messing with null are the last thing I think they should be doing.
Integer a = 10, b = 10 ;
Integer c = 129, d = 129 ;
System.out.println( a == 10 ) ; // A
System.out.println( a == b ) ; // B
System.out.println( c == 129 ) ; // C
System.out.println( c == d ) ; // D
But that's my point (I think)... It's cool, but when weighed against the pitfalls it adds, was it really worth it?
It just feels like it was added so that when selling the technology to new users, the word "Autoboxing" could be stuck in a callout box (probably star shaped, with an exclamation mark after it)
We could have stuck with:
List<Integer> list = new ArrayList<Integer>();
for( Integer i : list ) {
int val = i.intValue() ;
if(val < 10) System.out.println("Less!");
}
Which is 30 more keypresses, and not had the confusion...
For a simple example like this, no it doesn't make much of a difference whether you use autoboxing or not (and yeah, it does seem like a "selling" feature of Java 5). But there are other examples too complicated to just insert which illustrate a more substantial benefit to autoboxing.
Since you really want to argue about autoboxing :-)
There is one problem with primitives, that you dont have with objects, and that is null.
I have seen much code, which returned Integer.MIN_VALUE or -1 when they could not find a result.
I have fixed non-deterministic bugs with this one. I would so much rather look for NullPointerException..
Au contraire, the problem is with objects, not primitives.
null is a useless substitute for an object; it's better to return an object that means 'nothing'. The fact that primitives can't represent null is not a problem with primitives, it just means that you should choose a different type instead of a primitive. You could throw an exception, or choose a more appropriate return type.
I lived through it during many foul years, but yes I too have solutions handy (I remember reading your post some time ago) to obliviate all doubt. However, I know way to many developers who finds this way over their heads :-)
I used Smalltalk at uni (too many years ago) and had real fun with Object and Null.
I'll admit to having been dubious about autoboxing, but this example goes a long way to convince me that it is a Very Bad Idea. But what is java actually doing and why? (I did see that it was the 129 that was causing the problem - is it a signed/unsigned artifact?) I do have the JSR, but haven't read it carefully enough to know what is going on.
As Ricky says below, when you rely on autoboxing for integers, the numbers -127 to 128 (inclusive) are cached, so "a == b" will give you true as it is comparing the exact same instances of Integer...
But when you step beyond this point to 129, each variable "c" and "d" get a new instance of Integer, so "c == d" will return false. Remember, when comparing two Integer objects with the equality operator, no unboxing will occur, it is still a straight instance comparison as before. But it can be confusing (heh, or made confusing when trying to give an example of why it is evil) ;-)
Ah, that makes sense. And since "==" between objects is not what you'd usually use, it probably doesn't impact too much code. But it is very odd behavior.
That's my issue with it too... It makes the language "unpredictable" as you have to know the underlying implementation in order to predict the outcome...
Because it uses Integer.intValue(int) to store the objects in the first place.
This one returns cached integer object when int is between -128 and 127, and "is likely to yield significantly better space and time performance". It was introduced with 1.5 so that autoboxing wouldn't be too costly.. :-)
>However, properties, closures, and messing with null are the last thing I think they should be doing.
Oh how I love closures. If Java supported closures and inline functions (like ECMAScript), I'd loathe the language a lot less.
I hear people bemoan what they refer to as 'syntax sugar' a lot - but as the owner of a sweet tooth, I can tell you that just about anything that reduces my lines-of-code is a Good Thing.
I think that's the plan - I'm looking forward to strong JRuby and ECMAScript support. I played with these (and BeanShell) recently in Eclipse, but with little success. When it's all smoothly integrated I'll be a happy camper.
Even thought the Java language may be "drifting away" as the article title suggests, I think the VM will be around for a long time - if perhaps only as a platform for the scripting languages.
The JVM is staying.. Could perhaps add a few more bytecodes, but yes... It is a good platform. Now if only we could have a compiler where you could plug in the features you would like in your language, or better support for building my code against other languages, then I would be rather pleased.
There's no reason why you should have to use a dynamically typed language just to write a closure; Java would actually benefit from closures, and the implementation as proposed by Neal Gafter is actually better than those that exist in most scripting languages.
Closures are function pointers with a fancy new name. They're a recipe for disaster, an invitation to writing incredibly buggy code that's impossible to read and harder to debug.
That's especially true when you combine them with code generation and let the function pointer refer to something that doesn't exist in the code you are writing but to something else that's created on the fly at compilation time.
You might think that, and they are similar (and also to Java anonymous classes) but there are at least a couple of differences. I think Martin Fowler gives the best explanation of closures, so start there. For your second point, the "incredibly buggy code impossible to read", perhaps that's the case with function pointers but again these aren't function pointers. The idea behind closures is to write *less* buggy code, that is *easier* to read.
Autoboxing is fine. The == comparison between objects is retarded; if that wasn't in the language (or was implemented differently) then you wouldn't be complaining about that aspect of autoboxing.
Also, because javac is obliged to make 'new Integer(40)' really a new object (as far as I know), then, if autoboxing hadn't been introduced, we'd have seen lots of code like that, which is wasteful, compared to Integer.valueOf(40). Integer.valueOf(40) is free to decide for itself whether to create a new object or use an existing one.
You can set your IDE to flag up autoboxing as a compile error/warning if you like. I did that for a while, until I realised that I was writing hard-to-read code for no apparent reason.
Arguably, the autoboxing could have been done at a different level, so that List was allowed.
Haha, in my opinion primitives should never have been added, and hence, this autoboxing falls just into the gorge between our beliefs. Wouldn't it be nice just to pick the features you liked instead?
Ooh are we moody today :-)
How about introducing macros of some kind. Whats your view on that? I used the Java Syntactic Extender once, and it did reduce some of these problems to me.
So I've been coding for 2 years now on 1.5, and while I was a little horrified when I heard about autoboxing, I have yet to encounter a single situation where it was a problem. Philophical argument, maybe, but in reality they work fine.
Generics also have cleared up the code in my mind. Maybe it's my design style, but I have yet to run cases where they look horrible, or contain more than one level of generic definition. I don't understand how people get to 4-5 levels. Sounds like overuse of containers.
Annotations I can live without, and continue to not use them. I don't like how they alter the visual appearance of the code. I would rather keep my code clear of annotations and use xml configuration. Visually they hit a barrier quickly, and their purpose is ultimately too vague leading to all sorts of wacky uses of them.
Finally, 2004 was also way before Ruby,correction Rails, got its 5 minutes. Also, in reality, these features had been in planning forever so to call it a "response" to Ruby is giving Ruby WAY too much credit.
Comments
bloid replied ago:
The thing that I don't like are those changes which are only there to save keypresses... Autoboxing for example, is a dreadful thing, and (imho) should never have been added...
I get the feeling some things are added for marketing purposes, and not to suit the needs of the development community at large... And others are added as they are hyped up and shouted about until they seem "important"
As the saying goes "The squeaky wheel gets the grease"
Maybe it's time the majority of developers stood up and said what they wanted, rather than letting java mutate with all these new facilities just because they are "cool"?
Or maybe I'm in the minority, and should just shut up ;-) hee hee
daniel replied ago:
Oh, I like autoboxing. I think it could have been done infinitely better, but it does simplify code in a lot of places. Unfortunately, it can also make certain algorithms devilishly confusing. *shrugs*
I do admit that I like the new scripting engine, and I really like the idea of operator overloading - as long as it's done better than C++. Personally, I really like Ruby's operator overloading implementation, though I don't know how practical that sort of impl would be for Java because of Java's inherant syntactical limitations. However, properties, closures, and messing with null are the last thing I think they should be doing.
bloid replied ago:
Autoboxing is the devils plaything: Consider:
Integer a = 10, b = 10 ;
Integer c = 129, d = 129 ;
System.out.println( a == 10 ) ; // A
System.out.println( a == b ) ; // B
System.out.println( c == 129 ) ; // C
System.out.println( c == d ) ; // D
What does it print out?
(A: true, true, true, false)
daniel replied ago:
Like I said, devilishly confusing. :-) But you have to admit that this is pretty cool:
List<Integer> list = new ArrayList<Integer>();
for (int i : list) {
if (i < 10) System.out.println("Less!");
}
bloid replied ago:
But that's my point (I think)... It's cool, but when weighed against the pitfalls it adds, was it really worth it?
It just feels like it was added so that when selling the technology to new users, the word "Autoboxing" could be stuck in a callout box (probably star shaped, with an exclamation mark after it)
We could have stuck with:
List<Integer> list = new ArrayList<Integer>();
for( Integer i : list ) {
int val = i.intValue() ;
if(val < 10) System.out.println("Less!");
}
Which is 30 more keypresses, and not had the confusion...
daniel replied ago:
For a simple example like this, no it doesn't make much of a difference whether you use autoboxing or not (and yeah, it does seem like a "selling" feature of Java 5). But there are other examples too complicated to just insert which illustrate a more substantial benefit to autoboxing.
bloid replied ago:
I'm sure they do exist... it's just I'm yet to find one ;-)
nbn4java replied ago:
Since you really want to argue about autoboxing :-)
There is one problem with primitives, that you dont have with objects, and that is null.
I have seen much code, which returned Integer.MIN_VALUE or -1 when they could not find a result.
I have fixed non-deterministic bugs with this one. I would so much rather look for NullPointerException..
Ricky Clarkson replied ago:
Au contraire, the problem is with objects, not primitives.
null is a useless substitute for an object; it's better to return an object that means 'nothing'. The fact that primitives can't represent null is not a problem with primitives, it just means that you should choose a different type instead of a primitive. You could throw an exception, or choose a more appropriate return type.
I cover a solution to this in my blog - http://rickyclarkson.blogspot.com/2006/09/using-strong-typing-to-eliminate.html
nbn4java replied ago:
I lived through it during many foul years, but yes I too have solutions handy (I remember reading your post some time ago) to obliviate all doubt. However, I know way to many developers who finds this way over their heads :-)
I used Smalltalk at uni (too many years ago) and had real fun with Object and Null.
jefu replied ago:
I'll admit to having been dubious about autoboxing, but this example goes a long way to convince me that it is a Very Bad Idea. But what is java actually doing and why? (I did see that it was the 129 that was causing the problem - is it a signed/unsigned artifact?) I do have the JSR, but haven't read it carefully enough to know what is going on.
bloid replied ago:
As Ricky says below, when you rely on autoboxing for integers, the numbers -127 to 128 (inclusive) are cached, so "a == b" will give you true as it is comparing the exact same instances of Integer...
But when you step beyond this point to 129, each variable "c" and "d" get a new instance of Integer, so "c == d" will return false. Remember, when comparing two Integer objects with the equality operator, no unboxing will occur, it is still a straight instance comparison as before. But it can be confusing (heh, or made confusing when trying to give an example of why it is evil) ;-)
jefu replied ago:
Ah, that makes sense. And since "==" between objects is not what you'd usually use, it probably doesn't impact too much code. But it is very odd behavior.
bloid replied ago:
That's my issue with it too... It makes the language "unpredictable" as you have to know the underlying implementation in order to predict the outcome...
Frothy replied ago:
Why does the last line print false?
Ricky Clarkson replied ago:
Because there are cached Integer values for -128 to +127. Above that a new Integer object is created every time it's requested.
Of course, this behaviour is liable to change.
nbn4java replied ago:
Because it uses Integer.intValue(int) to store the objects in the first place.
This one returns cached integer object when int is between -128 and 127, and "is likely to yield significantly better space and time performance". It was introduced with 1.5 so that autoboxing wouldn't be too costly.. :-)
Jim Wilson replied ago:
>However, properties, closures, and messing with null are the last thing I think they should be doing.
Oh how I love closures. If Java supported closures and inline functions (like ECMAScript), I'd loathe the language a lot less.
I hear people bemoan what they refer to as 'syntax sugar' a lot - but as the owner of a sweet tooth, I can tell you that just about anything that reduces my lines-of-code is a Good Thing.
bloid replied ago:
With the new scripting API, can't these be farmed out to languages which do include them?
Jim Wilson replied ago:
I think that's the plan - I'm looking forward to strong JRuby and ECMAScript support. I played with these (and BeanShell) recently in Eclipse, but with little success. When it's all smoothly integrated I'll be a happy camper.
Even thought the Java language may be "drifting away" as the article title suggests, I think the VM will be around for a long time - if perhaps only as a platform for the scripting languages.
nbn4java replied ago:
The JVM is staying.. Could perhaps add a few more bytecodes, but yes... It is a good platform. Now if only we could have a compiler where you could plug in the features you would like in your language, or better support for building my code against other languages, then I would be rather pleased.
Ricky Clarkson replied ago:
There's no reason why you should have to use a dynamically typed language just to write a closure; Java would actually benefit from closures, and the implementation as proposed by Neal Gafter is actually better than those that exist in most scripting languages.
jwenting replied ago:
Closures are function pointers with a fancy new name. They're a recipe for disaster, an invitation to writing incredibly buggy code that's impossible to read and harder to debug.
That's especially true when you combine them with code generation and let the function pointer refer to something that doesn't exist in the code you are writing but to something else that's created on the fly at compilation time.
mo74395 replied ago:
You might think that, and they are similar (and also to Java anonymous classes) but there are at least a couple of differences. I think Martin Fowler gives the best explanation of closures, so start there. For your second point, the "incredibly buggy code impossible to read", perhaps that's the case with function pointers but again these aren't function pointers. The idea behind closures is to write *less* buggy code, that is *easier* to read.
http://www.martinfowler.com/bliki/Closure.html
Here's the Groovy version:
http://groovy.codehaus.org/Martin+Fowler%27s+closure+examples+in+Groovy
Ricky Clarkson replied ago:
Autoboxing is fine. The == comparison between objects is retarded; if that wasn't in the language (or was implemented differently) then you wouldn't be complaining about that aspect of autoboxing.
Also, because javac is obliged to make 'new Integer(40)' really a new object (as far as I know), then, if autoboxing hadn't been introduced, we'd have seen lots of code like that, which is wasteful, compared to Integer.valueOf(40). Integer.valueOf(40) is free to decide for itself whether to create a new object or use an existing one.
You can set your IDE to flag up autoboxing as a compile error/warning if you like. I did that for a while, until I realised that I was writing hard-to-read code for no apparent reason.
Arguably, the autoboxing could have been done at a different level, so that List was allowed.
nbn4java replied ago:
Haha, in my opinion primitives should never have been added, and hence, this autoboxing falls just into the gorge between our beliefs. Wouldn't it be nice just to pick the features you liked instead?
Ricky Clarkson replied ago:
"primitives should never have been added"
Then all those evil C++ programmers (ahem, like me) would have avoided Java like the (Smalltalk?) plague.
nbn4java replied ago:
Yes :-) and like me.
The fact that C++ was building on C actually was great for having both worlds, yet for OO design it was real hard...
Ricky Clarkson replied ago:
And it resulted in retarded design decisions like the 'final' requirement on local variables accessed from a local class.
nbn4java replied ago:
Ooh are we moody today :-)
How about introducing macros of some kind. Whats your view on that? I used the Java Syntactic Extender once, and it did reduce some of these problems to me.
ilazarte replied ago:
So I've been coding for 2 years now on 1.5, and while I was a little horrified when I heard about autoboxing, I have yet to encounter a single situation where it was a problem. Philophical argument, maybe, but in reality they work fine.
Generics also have cleared up the code in my mind. Maybe it's my design style, but I have yet to run cases where they look horrible, or contain more than one level of generic definition. I don't understand how people get to 4-5 levels. Sounds like overuse of containers.
Annotations I can live without, and continue to not use them. I don't like how they alter the visual appearance of the code. I would rather keep my code clear of annotations and use xml configuration. Visually they hit a barrier quickly, and their purpose is ultimately too vague leading to all sorts of wacky uses of them.
Finally, 2004 was also way before Ruby,correction Rails, got its 5 minutes. Also, in reality, these features had been in planning forever so to call it a "response" to Ruby is giving Ruby WAY too much credit.
mo74395 replied ago:
Agreed, all the 1.5 features was in fear of C#, which seems to have dissipated, replaced by dynamic language fear.
Voters For This Link (20)
Voters Against This Link (0)