Isn’t Java a Civilised Language?

A few weeks ago I was given the opportunity to learn iOS programming. My boss decided that I was more of a ‘computer scientist’ rather than a developer, and this meant that I could apply my knowledge to developing an iPad application or two – all I’d need to do was to learn Objective-C and the iOS SDK: after all, how hard can it be?

Although I’ve done lots of C/C++ in the past, I’ve been doing Java since 2001, so I’d virtually forgotten much of what I knew, and besides, Objective-C isn’t much like C++ anyway. The result is that you feel like you’ve washed up on a foreign shore unable to speak the language and you’re armed with nothing more than a sun tan and a dictionary.

In learning all this new stuff, I came to realise that Java is a VERY good language and the reason is, firstly and foremost, because you don’t have to think about memory allocation and deallocation, you can just get on with writing your application. In writing iOS applications in Objective-C, you have to both allocate memory for your objects and then clear up after yourself, returning your object’s memory back to the free-pool. This seems very old school for the second decade of the 21st century. Furthermore, having allocated memory for an object, you have to keep track of the number of references there are to it – a practice known as reference counting, something I first came across in my previous life as a C++ programmer. The fundamental idea here is that every time you create a new reference to an object, you increment the reference counter and when you’ve finished with the object reference you decrement its reference counter.

When the counter reaches zero, the the system releases the memory back to the free pool. In Objective-C, the function to decrement the reference count is called release; hence if Java had reference counting and if I wanted to, for example, ask an AddressService to find me an address, I’d need to do something like this:

// create an object and set the reference count to 1
    AddressService addressService = new AddressService();  
    // Use the object
    Address address = addressService.findAddress(id);
    // pass it to a method
    model.addAttribute("address", address);
    // free the memory 
    addressService.release();

That’s the simple scenario, but what happens if some method or other passes you an object reference as a method argument? In that case you have to decide how you’re going to hang on to it and there seem to be two ways of doing this. The first is to make a copy of the object and the second is to increment its reference count. Making a copy is probably the safest idea, but consumes more memory and will be slower, whilst incrementing the reference count is quick but not as safe as some other part of the program may get the reference counting wrong and decrement the count one too many times, which means that you’ve got a reference to some memory that may have been released, and when you try to access your released object your program will crash…. Again, if Java had reference counting then a Spring Controller request handler method would look something like this:

@RequestMapping(value = "/find", method = RequestMethod.GET)
  public String findAddress(@RequestParam("id") int id, Model model) {
    
    // increment the reference count - 'retain' is the Objective-C method for doing this.
    model.retain();    

    // create a new string object - with reference count of one
    String msg = new String().withFormat("Processing an address page request for address with id: " + id);
    // pass the string to the logger
    logger.info(msg);
    // release the string's memory
    msg.release();

    AddressService addressService = new AddressService();
    Address address = addressService.findAddress(id);
    model.addAttribute("address", address);
    addressService.release();

    // finished with the model
    model.release();
    return "address-display";
  }

There are a couple of points to note here – firstly, the handler method is passed a model object, so I increment the reference count by calling retain and then call release on the model when I’m finished with it at the end of the method. Secondly, even when creating trivial objects, like a message string that’s passed to a logger, you have to apply the reference counting rules and free the memory once you’ve finished with it.

The example below demonstrates the alternative to incrementing the reference count: making your own copy of an object…

@RequestMapping(value = "/find", method = RequestMethod.GET)
  public String findAddress(@RequestParam("id") int id, Model model) {
    
    // increment the reference count - 'retain' is the Objective-C method for doing this.
    Model myModel = model.copy();    

    // As previous example
    
    // finished with the model
    myModel.release();
    return "address-display";
  }

These examples are only trivial, there’s a whole bunch of reference counting rules that you need to apply and if you get it wrong then Ka-Bam your program crashes and getting it wrong means either you try to access memory that’s already been freed, or slowly die due to a memory leak because you’ve forgotten to release some memory. Although I guess that the key point here is ownership: if you own an object, increment it’s reference count, when you’re finished with an object then decrement its reference count.

The code above is just a bit of scribble written to illustrate the point – it won’t compile. The code was actually taken from my Address sample on GitHub and in real life looks like this:

@RequestMapping(value = "/find", method = RequestMethod.GET)
  public String findAddress(@RequestParam("id") int id, Model model) {

    logger.info("Processing an address page request for address with id: " + id);

    Address address = addressService.findAddress(id);
    model.addAttribute("address", address);

    return "address-display";
  }

…much smaller neater and more understandable. One last point, some of you will have noticed that in the reference counting example, I allocate (Objective-C word) a new AddressService - this is because iOS programming has nothing like dependency injection or a Spring framework, so you’re back to creating objects for yourself. (Note to the Guys at Spring: ‘Spring iOS’ – sounds like an idea to me…)

Those of you in the know will highlight the fact that Apple recently introduced something called ‘Automatic Reference Counting’. Whilst it isn’t garbage collection, it’s simplifies things in that iOS will now automatically keep track of your pointer references and free memory for you when the count reaches zero, which means that you don’t have to bother calling the retain and release methods.

Also, this blog isn’t trying to denigrate Objective-C – I quite like Objective-C. Its syntax seems rather arcane and feels verbose when compared to Java, but it forces you to be more disciplined in your programming technique, so if like me you believe that good programming is down to ‘clarity of thought’, then when writing an Objective-C program you have to think a little bit more clearly, and that I really like.

I also guess that a lot of readers might come up with a whole bunch of reasons as to why they think Java is a terrible language, and why their preferred language ‘does it better’, whatever it might be, so I’m looking forward to your comments…

Finally, I’m just a ‘newbie’ when it comes to iOS programming, so if any iOS/Objective-C masters come across this blog – please let me know where I’m wrong.

Reference: Isn’t Java a Civilised Language? from our JCG partner Roger Hughes at the Captain Debug’s Blog .

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

3 Responses to "Isn’t Java a Civilised Language?"

  1. rajiv says:

    Seems like a lot of your points are on a garbage collected language vs a manually managed language and not necessary java vs objective c.

  2. Mike says:

    Plus, have you taken a look at ARC?
    http://en.wikipedia.org/wiki/Automatic_Reference_Counting
    Manual memory management is on the way out. And I find the ARC concept better than garbage collecting.

  3. I fully agree with what you wrote about the benefits of automatic memory management (aka Garbage Collection). However, as the previous poster said, iOS now supports ARC – although I prefer real GC as it takes care of cycles etc.

    The most important thing however is: Even with Java and its magical GC, you can still end up having memory leaks if you are not careful. So regardless of the language, you should really know what you’re doing and therefore need a rough idea when memory is allocated and when it will be released.

    That being said, it’s of course a nice thing not to care about each and every little byte allocated for local computations etc. And as a bonus, Java gives you pooled allocation for free. So if you have an inner loop which frequently creates and (implicitly) frees an object, the JVM will probably reuse the same memory for all this, avoiding lots of mallocs/frees.

Leave a Reply


eight + 5 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books