Opinionated comments on mobile phone industry news
|
All entries are written by Anders Borg, CEO and Consultant of Abiro, that has a long experience in strategic planning, developing embedded and Java software, usability aspects, and the mobile phone industry in general. You can also read the latest Mobile News entries on your phone via wap.abiro.com, and we provide many News Feeds from popular news services. For advertising and contribution queries, please use the feedback form. News feed (local) |
|
Tuesday, October 17, 2006
Opinion on Java: Is Java using pointers?
This is probably the most technical note I've written so far. You are warned.
This slightly off-topic entry is intended to cover a subject that I think the Java literature gets all wrong, trying to abstract something that doesn't need abstracting. Rather it makes it "magical", while it's pretty down-to-earth when you take a closer look. As programming is a precise art, any sense of magic is completely out of place, even for beginners. Even more so when coding for Java ME, due to the memory and performance issues on phones.
A simple fact: Java uses pointers for pretty much everything. Sure, they are more type-safe and much more managed than in e.g. C and C++, where use of pointers is outright dangerous. Java also has a much cleaner syntax for object use.
In Java-speak it's called references, but frankly it's all about pointers, so I use that term below.
When you write "[class] [name];" you don't declare an object. You are just declaring a pointer to an object. [name] can point to any object of type [class] as well as derived such.
It's first when you do "[name] = new [class];" or "[name] = [object];" that you actually assign [name] the pointer to a specific class instance (= object).
This also means a statement like "somefunction(new [class]);" makes complete sense, as what you do is allocate an object on-the-fly and then pass its pointer to the function.
As the pointer is passed to the function you can also alter the object within the function, and changes are normally retained when exiting the function. Not in the above implicit case though, as when the function returns there's no variable pointing to the object any more and the object will hence be removed.
"null" serves as an indicator that a pointer variable hasn't been assigned any pointer to an object. It can also be used to de-reference objects. Always a good habit when objects are no longer used.
All objects are stored on the heap, and once there are not live pointers to any object they can be removed by the garbage collector.
Another area of possible confusion is arrays of objects. E.g. "[class][] [name];" only allocates a pointer variable to a possible object that's an array of pointers to possible [class] objects. When you then do "[name] = new [class][10];" you don't create an object with 10 instances of [class] but just 10 pointers to objects of type [class]. It's first when you do something like "[name][4] = new [class];" that you actually create an object for the array.
The only exception from the above rules is primitive types (e.g. int). That's also why there are container classes to make them behave as real classes and objects.
Another area that might seem magic is the creation of a class instance. What happens is that space is alloced for the object on the heap, variables are initialized with default values (as per the class definition) and the appropriate constructor is called. If there are several constructors, the one with the right argument types is called (overloading).
Other object tidbits (and suggestions for improvements of the Java language):
In e.g. Visual Basic, PHP etc a string is considered a primitive type, which makes text management very easy. In Java you can concatenate strings with "+", but apart from that a String object is like any other object, which is evidenced by e.g. the less than intuitive method for comparing strings "str1.equals(str2)". It hadn't hurt if e.g. "==" also worked for strings, as it's used so much. Also, String objects are immutable (constant), so appending strings to a larger string is very inefficient and memory-consuming. StringBuffer comes to the rescue here, but to me the string handling in Java seems a bit too manual for Java to be considered a high-level language. The benefit is that you can get the efficiency you want.
Any class can have a "equals" method that should implement an appropriate comparison of similar-typed objects. Considering this, it's kind of strange that the "switch" statement only handles values of integer type. Rather it should use the equals method to allow e.g. strings and even more advanced objects.
This slightly off-topic entry is intended to cover a subject that I think the Java literature gets all wrong, trying to abstract something that doesn't need abstracting. Rather it makes it "magical", while it's pretty down-to-earth when you take a closer look. As programming is a precise art, any sense of magic is completely out of place, even for beginners. Even more so when coding for Java ME, due to the memory and performance issues on phones.
A simple fact: Java uses pointers for pretty much everything. Sure, they are more type-safe and much more managed than in e.g. C and C++, where use of pointers is outright dangerous. Java also has a much cleaner syntax for object use.
In Java-speak it's called references, but frankly it's all about pointers, so I use that term below.
When you write "[class] [name];" you don't declare an object. You are just declaring a pointer to an object. [name] can point to any object of type [class] as well as derived such.
It's first when you do "[name] = new [class];" or "[name] = [object];" that you actually assign [name] the pointer to a specific class instance (= object).
This also means a statement like "somefunction(new [class]);" makes complete sense, as what you do is allocate an object on-the-fly and then pass its pointer to the function.
As the pointer is passed to the function you can also alter the object within the function, and changes are normally retained when exiting the function. Not in the above implicit case though, as when the function returns there's no variable pointing to the object any more and the object will hence be removed.
"null" serves as an indicator that a pointer variable hasn't been assigned any pointer to an object. It can also be used to de-reference objects. Always a good habit when objects are no longer used.
All objects are stored on the heap, and once there are not live pointers to any object they can be removed by the garbage collector.
Another area of possible confusion is arrays of objects. E.g. "[class][] [name];" only allocates a pointer variable to a possible object that's an array of pointers to possible [class] objects. When you then do "[name] = new [class][10];" you don't create an object with 10 instances of [class] but just 10 pointers to objects of type [class]. It's first when you do something like "[name][4] = new [class];" that you actually create an object for the array.
The only exception from the above rules is primitive types (e.g. int). That's also why there are container classes to make them behave as real classes and objects.
Another area that might seem magic is the creation of a class instance. What happens is that space is alloced for the object on the heap, variables are initialized with default values (as per the class definition) and the appropriate constructor is called. If there are several constructors, the one with the right argument types is called (overloading).
Other object tidbits (and suggestions for improvements of the Java language):
In e.g. Visual Basic, PHP etc a string is considered a primitive type, which makes text management very easy. In Java you can concatenate strings with "+", but apart from that a String object is like any other object, which is evidenced by e.g. the less than intuitive method for comparing strings "str1.equals(str2)". It hadn't hurt if e.g. "==" also worked for strings, as it's used so much. Also, String objects are immutable (constant), so appending strings to a larger string is very inefficient and memory-consuming. StringBuffer comes to the rescue here, but to me the string handling in Java seems a bit too manual for Java to be considered a high-level language. The benefit is that you can get the efficiency you want.
Any class can have a "equals" method that should implement an appropriate comparison of similar-typed objects. Considering this, it's kind of strange that the "switch" statement only handles values of integer type. Rather it should use the equals method to allow e.g. strings and even more advanced objects.

