Tim has posted 1 posts at DZone. View Full User Profile

Sometimes Java Makes Me Sad

08.06.2008
| 10819 views |
  • submit to reddit

On any given day I go back and forth as to whether I truly like Java as a language or not. On one hand the automatic memory management is really quite nice. However it has it’s downsides. Normally I find little quirks of the language that I really wish it had. First off, Java does not have unsigned integers. Now, this is not a true tragedy, and one can work around this by using long integers and bit operations. However that is normally too much work when one is just looking for a safer type.

Another downfall of Java is the pointer hiding. There are times when I really really want to be able to see exactly what is going on. (Yes I know every object is technically a pointer) There is one place in particular this has come to annoy me. I was trying to have a function change the value of an int. This would be quite easy in C or C++, but in Java it is rather tricky. Since you can’t pass the int as reference (Java only has pass by value) and the Integer class is Immutable. One hack I found was to declare an int array with a single element and pass that to the function:

public class TesterClass
{
    public static void main(String args[])
    {
     int[] fooArray = new int[1];

     fooArray[0] = 42;

     System.out.println("My val == " + fooArray[0]);
     myFunc(fooArray);
     System.out.println("My val == " + fooArray[0]);
    }

    public static void myFunc(int[] changeMe)
    {
     changeMe[0] = 12345;
    }

}

Which brings me to my next topic… why is the Integer class immutable!? Say I have the Integer class inside an ArrayList. Well I can’t simply change the value of that Integer. Why? Well because the creators of Java feel the Integer class should be immutable. To me, this makes no sense at all. Yes, I could simply make my own Integer class which allows for changing the underlying value, but why should I? Isn’t this a basic feature that it should have?! It could just have a .setValue() function. Simple! In my mind this makes using the primitive wrappers inside an ArrayList rather useless because you’d have to remove and insert them all the time if you have to change their values. Now, perhaps this is how the creators of Java wanted it. I suppose I will never know.

Overall I do like Java as a language, but sometimes I get discouraged by the potential issues of speed loss, and by some of the things I mentioned above. The control C++ gives the coder is hard to give up, and for now C++ will remain my favorite language :)

From http://jintoreedwine.wordpress.com

Published at DZone with permission of its author, Tim Mills.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

ff aaa replied on Wed, 2008/08/06 - 3:56am

 i think immutability of an Integer is not a bad thing. If what you need is pure speed, use primitives. If you cannot, object creation is very cheap anyway (cheaper than C++). if you feel a need of changing the value of an Integer, or pass by reference , you should check your approach to the problem. most likely you are not thinking Java way.    you should let go C++ way of thinking while coding in Java. Let JVM do the dirty job for you.

Lemaire Raphael replied on Wed, 2008/08/06 - 4:08am

You think in low level mode. Java is about strong typing and object orientation.

You may encaspulate your data in a class that make sense for your problem, and the need for pointers will disapear.

 

Ricky Clarkson replied on Wed, 2008/08/06 - 4:11am

I too find Java has many quirks that I don't like, but the things I don't like are quite opposite to yours (I agree about unsigned types).

Firstly, data structures that you write should not default to being mutable - e.g.: class Complex { double real, imag; } - it makes far more sense to make those fields final, but adding final everywhere can look quite ugly - it's a shame to make better code look worse.  At least they hard-coded immutability into some basic types like Integer, which seems to be what you're complaining about.

"I was trying to have a function change the value of an int"

This is called pass-by-reference, and encourages invisible state changes.  I suggest returning the value instead, then you don't force the caller to use mutable variables - so then they can call the method inline.  One problem with that is that in Java it doesn't work well for more than one value, e.g., you can replace:

void doubleIt(ref int x) { x *= 2; } with: int doubleIt(int x) { return x * 2; } but it gets harder to do for something like void swap(ref int x, ref int y), because you can't easily return a pair (no tuple types).

There are always ways though - you can have a pair type, and actually use it with generics to gain n-tuples (http://javatuple.com/  expands on this, as does my blog).

The JVM is specifically optimised for creating large numbers of short-lived objects, so it is not a real performance problem to create 2 Integer objects instead of modifying 1, and the reliability benefits of not changing things (especially, but not only, with concurrency) are massive.

Think about how code would break if Integer.valueOf(1).setValue(2); were allowed (this would affect every following Integer.valueOf(1) call, as the objects are pooled, according to the language spec).  Or for String, if "".setCharArray("my house") were allowed.

I suggest you dump C++ in favour of languages that promote reliability.  Java is a step up, but there are far better.

John Denver replied on Wed, 2008/08/06 - 4:44am

I love Java, It's one of the best languages and successful around but dont dump C++ just yet, If you check the ISO C++0x it is coming next year, You will see have many goodies as type inference, closures, concurrency, concepts, optional garbage collector you can decide if needs a garbage collector. I think with this update C++ is a language on a par or more capable than Java.

I think they missed with Java 7. I guess maybe closures, type inference, reified generics are my favorites and many more will not make it to Java 7.

I suggest use the right tool for the job and keep Java and C++, usally Java for Enterprise Business projects and C++ when speed matter or with the C++0x it will be a fun language again with my favorites type inference and closures.

Best Regards.

 

 

Mario Schwede replied on Wed, 2008/08/06 - 4:48am

Mutability of classes make programming robust software very hard. I just hate the Calendar class, because I have to make a defensive copy, every time I return it as an internal state. Immutability simplfies programming. For example you dont have to think about threadsafty. Of course, there are many classes, it dont make sense to make them immutable, but in my opinion value classes like Long, Integer, BigDecimal, String... have to.

Ryan Fleming replied on Wed, 2008/08/06 - 4:59am

It's also worth noting that one should put immutable objects as keys into Maps and such.

Anonymous Coward replied on Wed, 2008/08/06 - 7:35am in response to: John Denver

What do you like in C++0x? I'm yet to find anything good about it with the possible exception of the Object construction improvements.

Vjekoslav Nesek replied on Wed, 2008/08/06 - 8:40am

Immutability is GOOD. Making classes immutable when possible makes your code more robust in along run. One of worst mistakes in java APIs is that java.util.Date isn't immutable and that SimpleDateFormat holds internal state while parsing/formatting.

 Immutable classes need no synchronization beetween threads, you can share them without fear and there is no need for locking. As we move to a multicore era this will become much more important. Because there is no possibility of a change immutable classes, just like final variables can be better optimized bymodern JITs.

 And you can use immutable classes a a key to a java.util.Map. This is a biggest reason why Integer and company are immutable. Original use case for this classes was to have some object to attach utility methods for parsing and so they are objects and can be used in data structures. 

 It would have been better that int-s, long-s and such are objects instead of primitives but technology in 1995 wasn't ready for that

Piero Sartini replied on Wed, 2008/08/06 - 9:27am in response to: Vjekoslav Nesek

[quote=vnesek]It would have been better that int-s, long-s and such are objects instead of primitives but technology in 1995 wasn't ready for that [/quote]

Did you ever hear about SmallTalk? ;-)

Mauricio Garavaglia replied on Wed, 2008/08/06 - 9:38am

Well I can’t simply change the value of that Integer. Why? Well because the creators of Java feel the Integer class should be immutable.

it's all about state superposition :) perhaps this could explain it better.

http://mgaravaglia.com.ar/blog/index.php/2008/06/04/la-inmutabilidad-de-los-objetos/ 

it's in spanish but I think we all trust in google translator :P

Madhu Siddalingaiah replied on Wed, 2008/08/06 - 11:41am

This sounds to me like a basic difference between OOP and procedural programming styles. Others have said this in so many words. You seem to prefer a procedural style. There's nothing wrong with that, but that's one of the basic differences between C++ and Java. Java is more in the OO camp than C++.

I'm not sure why you need unsigned integers, it has never caused a problem for me. It's the same number of bits in either case.

Try Smalltalk when you get a chance, it's the ultimate in OOP. Smalltalk does not expose pointers either. The two big differences between Smalltalk and Java are static typing and native primitives. There are many more differences between C++ and Smalltalk.

Squeak is a good, free Smalltalk implementation.

Madhu

 

Tim Mills replied on Wed, 2008/08/06 - 12:08pm

I think I need to take a bit of time to clarify some things here :)

 1. I am not against things being immutable. Certainly they have many uses and make for more robust code which is less error prone. Perhaps I should have said that it would be nice if Java included a MutableInteger class for the times when it would be nice to have one. I know that the 'Java way' is to just declare objects when you need them, and let the garbage collector deal with the rest, but I don't want to put myself in a position to have the garbage collector  being invoked too often. 

2. In the spirt of robust code is the unsigned integer. When a value cannot be negative, being able to use an unsigned int is very convient. For instance: when indexing an array. That is why I think unsigned integers are important. Again, this is not essential, but it is nice to have. 

3. I like Java, despite what I believe are its downsides. So I hope people don't read this as me bashing Java and trying to promote C++ (that truly was not the intent) :)

4.  In terms of my sample code. I know it is a trival example, and that I could have just returned the value :), but there are times when you would need to return more than one thing in which case having pass by reference is quite nice. Yes, I could have a templated 'Pair' class, or some such construct, but then I need all that extra code which defeats some of the arguements about the return value making for more readable code. Plus, then I have to allocate one of those 'Pair' objects every time the function is called. 

5. I like both Java and C++. I think it is good to know both of them and they each have their uses. 

I hope that clears some things up :)  Thanks for all the feedback!

Doug McCreary replied on Wed, 2008/08/06 - 12:39pm

I think a significant part of the spirit of java is to discourage novice mistakes.   Raising the bar on the level of stupidity required to write bad code as it were.  With that in mind:

 Immutables discourage hidden state change.  As others have pointed out immutability is a requirement for various features.  You can work around the immutability as needed, but Java correctly discourages you from doing so without at least giving careful thought to what you are doing.

Having signed types only eliminates the possibility of sign conversion errors (and doesn't matter to indexing: either you or the machine have to bounds check one side in either case, and having the machine do it eliminate the possibilty that you'll make the mistake or that you'll waste time bounds-checking both sides).

 

Lemaire Raphael replied on Wed, 2008/08/06 - 1:26pm

1) I have already found myself writing a MutableInteger class (an that's the actual name I gave to it). That was for a Data Mining project where I stored counters in a map (which keys were Strings). The project was parsing very large files (about 700mo if I remember well), and needed to do its job in less than half an hour, so on this project, performance was important, and replacing the destruction and creation of the value in the map (which was an Integer) which a mutable primitive handler helped me to gain something. In fact I heard it was for performance reasons that primitives were included in Java. By the way I never needed this class again, and I think that a language is clearer with only one type of type.

2)  The possibility to have unsigned primitives doubles the complexity of the primitives types. For most array, you will never go ahead of the Integer.MAX_VALUE limit, and a monstruous ArrayIndexOutOfBoundsException will warn you about negatives indexes if you hadn't used an assert. When possible you should use the cute foreach loop.

 3) To me 'Pair' is not a good return type,  you may return something that has something to do with your (domain) problem. That's why the conceptors of java (influenced by smalltalk) didn't put the pass by reference in the language : you can overcome it via more object orientation, and it makes the program simpler.

 

When you use a langage you should ask yourself what is the feeling of it. C++ is an elitist langage with strong roots in the procedural C (that should compile in C++), and a big focus on performance. Java  is a full Object Oriented langage inspired mainly by C++ and smalltalk, which was for a long time pretty slow, and focus on writing big maintainable programs via simplicity and strong typing.

You seem to be nostalgic of some old school features (like pointers), although many of us (like me) are looking forward to younger langages that are even farthest for C (higher level, no more ';' (yeah ! useless !), no more primitives ...) 

 

Tim Mills replied on Wed, 2008/08/06 - 8:46pm

"You seem to be nostalgic of some old school features (like pointers), although many of us (like me) are looking forward to younger langages that are even farthest for C (higher level, no more ';' (yeah ! useless !), no more primitives ...) " --Quote from Raphael_Lemaire

 Yes, there are times when I appreciate the performance gains of pointers :)  I do enjoy some good C coding as well, but I use (and enjoy) languages like Java, and even Python. I am simply pointing out some of the things of Java that make me still think there is a place for C++  :)  I would not hesitate to use Java on a big project if I was convinced I didn't need the benefit of direct pointer access, or that there was a sufficient work around. In fact I have a personal project (http://sourceforge.net/projects/spheriosity/) that I develop in Java. 

Perhaps I just enjoy what I first learned too much? 

I appreciate everyone's thoughtful remarks!

Dapeng Liu replied on Thu, 2008/08/07 - 2:00am

imo, pointers are plain bad ideas in general programming

you have to answer "am i working with some real thing or juz the pointer ??"

everytime you encounter a var, this is juz plain pain ...

 

 

Alexander Shirkov replied on Thu, 2008/08/07 - 2:42am

1) Why Integer is immutable. Primitives itself are immutable (if this state can be applied to them). The second point - caching of widely used values - you're getting perfomance benefits from caching. If you look the code, you can see, that the only way to perform caching is to hold Integer immutable.

2) Pure C++ often faster in calculations. Actially many Java classes using the power of C++ (for example, java.lang.Math class - internally it uses Freely Distributable Math Library). Nothing stops you from doing same thing, when you need to gain perfomance benefits from C++.

Daniel Glauser replied on Thu, 2008/08/07 - 10:32am

"I am not against things being immutable. Certainly they have many uses and make for more robust code which is less error prone. Perhaps I should have said that it would be nice if Java included a MutableInteger class for the times when it would be nice to have one. I know that the 'Java way' is to just declare objects when you need them, and let the garbage collector deal with the rest, but I don't want to put myself in a position to have the garbage collector  being invoked too often."

I think you may misunderstand how the garbage collector works.  If you picture it as a "living object saver" rather than a garbage collector it might make more sense.  It's easy to picture the garbage collector as a costly operation that runs every once in a while, cleaning things up and completely hosing the JVM.  That's not the case.  The garbage collector keeps track of reachable object and lets the rest to free memory.  So the perceived cost of having your method return a new Integer may be much less than you think.


I see your point about missing the elegance of pointers when you want to return a pair (Integer, Integer) and don't want the overhead of a new class called Pair.  However, after coding C and C++ for a couple of years I became sick of seeing code that would return a pointer to two pointers, the first referring to a String array, the second referring to a struct containing a three pointers to other data structures, etc.  I find object graphs unnecessarily difficult to follow when they are laid out like this, I would much prefer the developer(s) took the extra time to create some simple classes.


Java doesn't force you to follow my second point, I often see developers with a lot of C experience creating Lists of Maps of Lists of Maps instead of taking a step back and designing a new data structure.  One guideline that has worked for me is to keep things to less that three levels of indirection with a generic data structure, whether it is pointers to pointers to structs to pointers or Lists of Maps of Lists of Maps.

Although I think you have a point that a new class seems to be overkill when you want to return a pointer to two integers I think the development overhead is worth the clarity.

 

Tib Onu replied on Thu, 2008/08/07 - 2:13pm in response to: Tim Mills

[quote]I would not hesitate to use Java on a big project if I was convinced I didn't need the benefit of direct pointer access[/quote]

In my experience, there is no benefit of direct pointer access, except for low-level programming. Java does indeed use reference pointers, but, thankfully, no pointer arithmetic. "The performance gains of pointers" in C++ vs Java is pure mythology. As are the claims regarding the performance penalties induced by the JVM memory model:

 http://www.ibm.com/developerworks/java/library/j-jtp04223.html?S_TACT=105AGX02&S_CMP=EDU

 

 Cheers,

- Tib

Mike P(Okidoky) replied on Thu, 2008/08/07 - 3:52pm

A very important advantage of Java is that you can not accidentally overrun a buffer. Every index is checked, and it does that very efficiently.

Pointers are a much worse alternative. When processing pixels, a C person might normally have a pointer pointing to a pixel, process that pixel, and then advance that pointer. In Java you'd have an int which is used to index into an array of pixels. Immediately you can't accidentally run off the end (or beginning) of a pixel buffer. The cost of having to "recalculate" the memory address because of having to use an index instead of a point is VERY minimal. The x86 can address a memory location using an index using one single instruction. You don't  even need to seperately "add" and "calculate" the destination address. And if it does it's very minimal. I've compared pointer based pixel buffer manipulations with Java indexing a number of times, and I could get the Java version often to perform actually BETTER than what I could do with C, believe it or not.

 

Christian Vest ... replied on Fri, 2008/08/08 - 7:51am

Actually, Java does have a mutable Integer class. It's called AtomicInteger and has the added advantage of being thread-safe. Also, the JIT in Java would not be able to do such a fine job if it wasn't for immutability and lack of pointer arithmetics in the language.

If you want both garbage collectors and pointers, then D might be your language. 

Slava Imeshev replied on Fri, 2008/08/08 - 5:45pm in response to: Christian Vest Hansen

[quote]

On any given day I go back and forth as to whether I truly like Java as a language or not.

[/quote]

Try to be a real man, move to C++ :-)

Regards,

Slava Imeshev

 

Tomasz Wermiński replied on Tue, 2011/04/19 - 10:03am

This is the reason of immutable Integer:

public void methodA(){
    int intVariable = 1;

    methodB(intVariable);

    System.out.println(intVariable); //what value should be written here?
}

public void methodB(Integer intVariable){
    intVariable.setValue(2);
}
Sorry for post mining ;P

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.