Thursday, February 17, 2011

What's a bean?

Java evolved from simply a language into an entire ecosystem of APIs and libraries and frameworks, more than any mere mortal can comprehend. You just cannot be an expert in all of them, as more are created every day, it seems, and the ones that were all the rage five years ago are now ground into dust beneath the wheels of what's newer and slicker. Some concepts still pervade a good number of them though, and one of them is the Java "bean".

There are many specific kinds of "beans", such as Enterprise Java Beans and MBeans and Persistent Entity Beans, but there is also just this general concept of a bean. Its origin is way back before the proliferation of APIs and frameworks, and the idea was that if you made a Java class just so, then tools, or other things that got a hold of your class, could find out things about it. A very simple set of conventions was determined, and if your class follows those conventions, then it's a bean.

Your class can be a bean and something else too. It's not a restrictive concept, like most Java concepts became for a while there. It really is only a set of conventions, a small one at that, which you can often adopt, and if you do, it can help you out.

Here are the conventions.

First, your class needs to have a public "no-arg" constructor; that is, it must be possible for code anywhere to make an instance of it by just saying new MyClass(). Fortunately, if you don't write a constructor for your class, Java makes a no-arg constructor for you. If you do write some other constructors, then you can just add this.
public MyClass() {}
Second, and this is kind of optional, your class needs to have properties. The idea behind a property is that you have a public getter and (if you like) a public setter method named similarly. Here:
public String getLastName() { return ln; }
public void setLastName (String n) { ln = n; }
The methods above define a read-write property called "lastName". Note that the property name starts with a lowercase letter. The getter takes no arguments and returns the property value, while the setter takes in a new value and returns nothing. If you want the property to be read-only, omit the setter.

The type of the property can be anything you like. One wrinkle: if it's boolean, use a different naming convention for the getter.
public boolean isAdult() { return (age >= 18); }
Inside your class, the property doesn't have to be represented by a field in a one-to-one relationship. Do whatever you like in there, but only expose publicly a named property of some type.

The third convention is ... well, I'm going to be a little ornery here and say that there aren't any more conventions you need to follow. The Wikipedia entry for JavaBean says your class should be serializable, which means that instances of it need to be able to be saved off and restored, but I don't think that's strictly required. (The entry itself says it "should" be serializable, so there.) And the official JavaBean spec has bits about beans exchanging events, but again I see that as optional if you want it.

So, in my ornery opinion, any Java class with a public no-arg constructor, and maybe with some properties, is a bean. There.

I claim this because by following these two simple conventions your classes can be wired into all sorts of neat things. The Apache Commons BeanUtils library is one of them, and while that library maybe isn't all that jazzy when used directly, it's the foundation for some really powerful Java technologies—just read the overview to see some examples.

Another powerful framework drawing from the bean concept is Spring, whose most fundamental offerings are all about creating and configuring objects for you as long as they are beans (well, often even if they aren't, but it really really likes beans).

I said above that "for a while there" Java concepts got restrictive. For example, the Java Servlet specification (which I still use all the time) says that, in order for a Java class to respond to HTTP requests, it has to extend a particular class HttpServlet and implement specific methods and use certain other classes and so on and so on. On its own, this is fine. But for a working Java developer, having to know this specialized set of classes for servlets, plus another for Enterprise Java Beans, and another for some other framework, well, it's a real pain. The community called out for a return to simplicity.

And so, frameworks like Spring and new language features like annotations arrived, and mercifully, the primary goals for these endeavors included "making your life easier so you can get your work done". One big way of making that happen was to leave the restrictive concepts behind and instead let you work with simple ones, like the humble bean. Then, after some hints and nudges, the heavy lifting would be done for you.

(If this sounds like you're encouraged to be lazy, then stop using Java and go work in assembly language. :) )

So, next time you're slapping some new classes together, think about making some of them beans along the way. It might not help you right away, but down the line that decision might pay off. Even the mere fact that the bean concept is a foundation for all these regions of the Java ecosystem should indicate that it's not a bad idea to adopt it for yourself.

Friday, February 4, 2011

Taking shortcuts

Now that I finished going through all of the Java operators, I want to talk about the special way that two of them work. Those two are the logical AND and OR operators, also known as && and ||. These guys can be lazy and skip part of their evaluation; sometimes this is good for you, and sometimes not.

Let's take logical AND. If both its operands in an expression are true, then the whole thing evaluates to true. Otherwise, the expression evaluates to false. That's just AND.

Now, let's focus on that first operand. If it evaluates to true, what does that tell you about the expression's value? Well, not much, you still need to check on the second operand. But suppose the first operand evaluates to false? If that happens, you know that the whole expression is false already. The value of the second operand doesn't matter.

Java takes this lesson to heart. If the first operand for logical AND evaluates to false, then it doesn't evaluate the second operand at all. This is called a shortcut or short circuit Boolean operation. It is good for efficiency, especially for something like this:
if (debugging && timeConsumingMethod()) {
  doSomething();
}
Because logical AND shortcuts, that really expensive timeConsumingMethod won't be called unless you are debugging. Might as well not pay the price if you can help it.

Logical OR works the same way, except opposite sorta. If the first operand in its expression is true, then it shortcuts, because the entire expression must evaluate to true at that point no matter what. For example:
if (answer == null || !(answer.equals ("apple"))) {
  wrongAnswer();
}
Without short circuiting, the equals() call would throw a nasty NullPointerException when answer is null. Instead, though, because OR shortcuts, it's safe. This is a common trick for dealing with nulls in comparisons.

While shortcut operations are useful, you do have to be careful with them. Avoid having the second operand do something as a side effect that you really want to happen all the time.
int i = 0;
while (i < a.length) {
  if (a[i] == null || a[i++].equals ("")) {
    System.out.println ("I found a blank!");
  }
}
This all-too-clever loop tries to run through an array of strings, looking for either nulls or empty strings. The loop index gets incremented with that i++ bit. As long as the array contains no nulls, this loop will work, but as soon as the first null arrives, because logical OR shortcuts, the loop will get stuck, printing out "I found a blank!" forever and ever, or until you hit Control-C.

(I don't think I've covered the while loop yet. It's a basic loop that keeps going "while" the Boolean expression next to while evaluates to true. If the expression is false to begin with, the loop never executes even once. So, you have to make sure you either make that condition false at some point, or break out of the loop using either break or return.)

The example above is a bit contrived, but traps like it can and do happen more subtly in real code.

Two more things. First, the bitwise AND and OR operators, known as & and |, do not short circuit. They are more akin to mathematical operations, so this makes sense.

Second, don't use the shortcut feature to implement flow control. This is something that is idiomatic in scripting languages, but it ain't the Java way. Here's some examples. First, the typical way you open a file in Perl.
open HANDLE, "<myfile.txt" or die "Cannot open myfile.txt";
The die command, which causes the script to exit, will not execute as long as the file is opened successfully.

Another example, from bash scripting:
[[ -n DEBUG ]] && echo File is opened.
If the DEBUG variable isn't set, the AND short circuits and the debug message isn't printed out.

While this is pretty nifty and all, doing the same thing in Java will likely lead to confusion, although it may help your geek cred. Eh, it's not worth it. Really, use if statements instead.