Globals In Java?

Elliotte Rusty Harold, author of Java I/O, has a few very nice blogs that I read often. He's a smart guy with a lot of experience in software development. In a recent post, however, I think he made an interesting point that I wanted to address.

He listed 10 things he dislikes about Ruby. I don't have a great deal of Ruby experience, so I can't speak on many of them. I do have a lot of Java experience however, and Java happens to be the language Elliotte seems to like the most.

The fourth thing he hates about Ruby is this:

4. Global variables

Didn’t somebody tell me Ruby was an object-oriented language?

To this, I would ask Elliotte to look back upon the language he promotes and ask the same question. Once upon a time, Java did not have global variables. In fact, I liked to ask in interviews "Why doesn't Java support global variables?" to see if interview candidates understand encapsulation.

After Java 5 was released however, Java did have globals. I understand they do not have "true" globals in the most literal sense of the world, but static import statements effectively brought globals into Java.

It has always been possible to provide the benefit of data that could be accessed without instantiating a class. Public static methods and variables have been used in Constants files and Util classes for some time. It is very often that one finds a Constants file with public static members, so that code can reference them easily: Constants.MAX_WIDTH, etc. Though that's less OO than would be ideal, it IS a good place for information that needs to be readily accessible. It provides the benefit of a global variable, but without sacrificing object-orientation. MAX_WIDTH still *BELONGS* to Constants, and that keeps a relationship active that makes it clear what belongs to what.

The situation is the same for Util classes. StringUtils, DbUtils, or what have you; they will have public static methods, so that code can easily call something like StringUtils.center(str,10). This, once again, gives the benefits of globally accessible methods WITHOUT sacrificing OO, since it's clear that the center method BELONGS to StringUtils. There is still a relationship that is preserved.

The ability to do static imports, however, completely ruins this. I can stick import static com.air0day.ex.Constants.* in the top of my Java source file, and suddenly the code it contains can reference MAX_WIDTH directly, without any concept of what class it belongs to.

Once upon a time, constants were written in a Constant interface, then classes that needed access implemented that interface. This worked for variables, except that the values could not be modified by code (handy to prevent one of the biggest problems with global variables), but provided no function access. As much of a hack as the constant interface methodology was, it did some good. It forced methods to belong to classes that provided them statically. It also allowed for code to reference constants directly (MAX_WIDTH instead of Constants.MAX_WIDTH) and it also prevented classes from modifying the values.

Static imports, however, allowed you to drop the class identifier when referencing static fields and static methods. Past a single import line in the head of a file, there is no concept of which classes to which fields and methods belong. Aside from that one line, these are global variables, plain and simple. They are generally public (they could be package scope, but that is unlikely), and if they need to be modified at all by one class, they can't be final, which allows any class to modify their values.

All of the advantages of global variables can be found with import static, and all of the disadvantages can as well. Though they go by a different name, and they still technically "belong" to a class, the effect they have on code is exactly the same. A global by any other name would confuse as much.

I don't particularly like import static, but I don't hate it either. At the same time, I recognize that it would be disinginuous to claim that Ruby is not OO because it has globals, but that Java is. If a language isn't OO because of globals (and I partially agree that it isn't), then Java is not an OO language.

Unleash This Post Upon Others:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Fark
  • YahooMyWeb
  • NewsVine
  • Ma.gnolia
  • blogmarks
  • co.mments
  • connotea
  • De.lirio.us
  • Furl
  • Netvouz
  • RawSugar
  • Reddit
  • scuttle
  • Shadows
  • Simpy
  • Smarking
  • Spurl
  • TailRank

One Comment

  1. abhi:

    I may be wrong here, but the main reason why static imports were called upon was that the only other way of including common data (interface implementation) made it (the data) a part of the classes public API. We ARE sidestepping that issue with static imports, and also, the qualification of the class name in the import statement means that there’s still a line between global data and utility constants, no matter how thin. This means that the programmer take the responsibility of making sure the client doesn’t get direct access to that data. To mantain the sanctity of OO principles, just don’t use static import, unless absolutely nessecerry.

Leave a comment