Daniel Pitts’ Tech Blog

Archive for the ‘Java’ Category

Baby.java

Thursday, February 4th, 2010

I’ve been spending more time taking care of my little girl lately, and I was thinking “this isn’t anything like programming.” I realized that it kind of is, just no one has written the JavaDocs so that programmers like me can understand it clearly.

So, I’ve taken it upon myself. Here you go.

// Baby.java
// Copyright(C) 2010, Daniel Pitts, All Rights Reserved.
import java.util.Collection;

/**
 * A Baby. A small child which acts similar to an adult, but has some
 * differences which may be surprising. Any method can throw TantrumException
 * at any time for no decernable reason. All methods are abstract, because
 * every baby is different.
 * <p>
 * Baby's aren't collected by the standard JVM Garbage collector, but
 * instead may be collected by Child Protection Services (CPS for short) if
 * not properly handled.
 */
public abstract class Baby {
    /**
     * Attempt to put baby down for a nap.  You may need to call any of the
     * following methods before this method will succeed.
     * <ul>
     *   <li>{@link Baby#recieve(Bottle)}
     *   <li>{@link Baby#change(Diaper)}
     *   <li>{@link Baby#feed(Meal)}
     *   <li>{@link Baby#change(Diaper)}
     *   <li>{@link Baby#giveAffection(java.util.Collection)}
     *   <li>{@link Baby#playWithToys(java.util.Collection)}
     * </ul>
     * @throws InterruptedException randomly
     * @throws TantrumException when the mood strikes
     * @throws IllegalStateException if the child doesn't want to sleep for
     * some reason or another.
     */
    public abstract void sleep() throws InterruptedException, TantrumException;

    /**
     * Attempt to give the baby a bottle.  Once the baby is done with the
     * bottle, the bottle may be returned or thrown.  This may happen
     * immediately, or after the bottle has been emptied.
     *
     * @param bottle a bottle of formula or milk.
     * @throws TantrumException when the mood strikes.
     * @throws Bottle the bottle, if the baby *really* doesn't want the bottle.
     * @return the bottle.
     */
    public abstract Bottle recieve(Bottle bottle)
            throws TantrumException, Bottle;

    /**
     * Attempt to change the baby's diaper.
     * @param diaper the new, clean diaper.  An attempt to use a dirty
     * diaper will result in a JVM error, and CPS will come by shortly to
     * remove the Baby from your care.
     * @return a dirty diaper. This diaper should be disposed of as soon
     * as possible.
     * @throws TantrumException when the mood strikes.
     * @throws PoopyDiaper if the parent doesn't remove the diaper quickly
     * enough.
     */
    public abstract Diaper change(Diaper diaper) throws TantrumException,
            PoopyDiaper;

    /**
     * Gives a snack to the baby.  May help prevent TantrumExceptions from
     * being thrown for some time.
     * @param snack something delicious and healthful.
     * @throws TantrumException if snack is null, or the wrong kind for the
     * moment.
     */
    public abstract void feed(Snack snack) throws TantrumException;

    /**
     * Gives a prepared meal to the baby.  May help prevent TantrumExceptions
     * from being thrown for some time, also prevents the baby object from
     * being reclaimed by CPS.  Must be called at least three times a day.
     * @param meal something nutricious and yummy.
     * @throws TantrumException at whim.
     * @return a mess which needs to be cleaned up. Older babies may return
     * null more frequently, but don't count on it.
     */
    public abstract Mess feed(Meal meal) throws TantrumException;

    /**
     * This method is very important to call, many times per day.  Remember,
     * the more love you pass in, the more you get back. The love can be Hugs,
     * Kisses, and Talking.
     * @throws TantrumException usually happens only when any of the
     * playWith methods are executing concurrently.
     * @return some love, often more than you give.
     */
    public abstract Collection giveAffection(Collection love)
            throws TantrumException;

    /**
     * Reads a story the baby. This is often a prerequisite for
     * {@link Baby#sleep()}.
     * @param story the story.
     * @throws TantrumException if the story is the babies favorite at the
     * moment, or if the baby realizes that bed-time comes after the story.
     */
    public abstract void read(Story story) throws TantrumException;

    /**
     * This method will be executed on its own from time-to-time.  Not all
     * objects passed in are actually toys, and may cause all kinds of
     * exceptions.  A strong attempt should be made to intercept all calls to
     * this method and filter out non-toys, or otherwise dangerous objects.
     * @param something something the baby thinks is a toy.
     * @throws TantrumException randomly, or sometimes if some object is
     * filtered.
     */
    public abstract void playWith(Object something) throws TantrumException;

    /**
     * Give the child a toy to play with.
     * @param toys something fun to play with.
     * @throws TantrumException once the child is tired of the toy, or if it
     * isn't the toy they wanted.
     */
    public abstract void playWithToys(Collection toys)
            throws TantrumException;

    /**
     * Have this baby play with another group of babies.
     * @param babies a group of babies to play with.
     * @throws TantrumException for many reasons.  Sometimes babies will take
     * toys from other babies, which often causes a TantrumException.
     */
    public abstract void playWithBabies(Collection<Baby> babies)
            throws TantrumException;

    /**
     * Bathe the baby.  Keeps the baby clean and happy. If you go too long
     * without calling this method, CPS will collect the baby.
     * @param bath a warm bath which should have some toys in it.
     * @throws TantrumException whenever.
     */
    public abstract void bathe(Bath bath) throws TantrumException;
}

JavaScript and Java applets

Saturday, October 11th, 2008

I know, Applets are almost dead, but we actually had use for them recently in a project.  We needed to upload multiple images at once, and since no one on our team knows Flash, we decided to use an Applet. Anyway, the trouble we came across was the Java to JavaScript bridge is flat-out broken.  What you are supposed to be able to do is well documented at Sun’s java_js page and Mozilla’s LiveConnect page. The trouble is, that they are wrong when it comes to calling a Java method from JavaScript. They also fail to mention the security implications of that altogether.

Signed applets with unsigned JavaScript

The first challenge we came to (which is actually the easiest to solve) was that we were getting AccessControlExceptions, even though we went through the trouble of signing the Applet jar. As it turns out, the permission context used is that of the JavaScript, so you need to elevate the permission to your Applets context, using AccessController, and PrivilegedAction.
Java:

public void javascriptCallsMe() {
    AccessController.doPrivileged(new PrivilegedAction() {
      public Void run() {
         // We can now
         readOrWriteFilesOrWhatever();
         return null;
      }
    });
 }

That solved that problem.

Passing JavaScript objects to Java

The next problem, which plagued me for a week, was that getting a JSObject in Java seems to be broken. There are two ways to get an instance of the netscape.javascript.JSObject class.  The first way, and this always seems to work, is the JSObject.getWindow(Applet applet).  This will get the JSObject wrapping the “window” browser object.  This is useful if you know the “path” to the JavaScript object your code cares about.  It is akin to using a static reference, and isn’t good design. The other way, is to have a Java method that takes an Object or JSObject reference: In Java:

public class MyApplet extends JApplet {
  public void doStuff(JSObject params) {
    System.out.println(params.getMember("foo"));
  }
}

Then in JavaScript you should be able to do this: documents.applets[0].doStuff({foo: "bar"}); Unfortunately, what really happens is you get a “broken” instance of JSObject.  Debugging the Applet, I found that the JSObject instance has a field called nac, which has a value for the JSObject.getWindow(…), but is null for values passed in from JavaScript. So, what solutions and work arounds have people come up with? None that I could find.  I searched high and low. Plenty of people have discovered this bug, but none of come up with a solution. Until now!  I thought about it and realized, JSObjects I get from the “window” JSObject all work, so maybe I can put my broken object into a working object, and pull it back out to get a working object. A little experiment proved that it worked (at least on FireFox, I’ll guess it works on IE too, anyone want to verify?). So, I decided to go ahead and create a JSObject resolver, that will fix any possibly broken object:

public class MyApplet extends JApplet {
  private JSObject appletTmp;

  public JSObject resolveObject(Object o) {
    final int hashCode = System.identityHashCode(o);

    appletTmp.setMember("toResolve" + hashCode, o);
    return (JSObject) appletTmp.getMember("toResolve" + hashCode);
  }

  public void init() {
    if (appletTmp == null) {
      final JSObject window = JSObject.getWindow(this);
      final String tmpName = "_AppletTmp" + System.identityHashCode(this);
      window.eval("var "+ tmpName +" = {}");
      appletTmp = (JSObject)window.getMember(tmpName);
    }
  }
}

Granted, this code doesn’t clean up after itself, so if you use it for a long time or on a lot of JS objects, you will need to add some clean up code to it. With that, I was finally able to fully use the Java Applet the way I wanted to: As a “service provider” to the JavaScript on our existing page.

Exceptional Exceptions!

Monday, July 21st, 2008

First, some boring philosophy about exceptions, then some interesting ways to circumvent the checked exception mechanism.

When designing your system, you should decide carefully which type of exception you want to throw. You have basically three choices: Errors, Exceptions, or RuntimeExceptions.

For unchecked exceptions, generally Errors shouldn’t be thrown directly, and RuntimeExceptions should be thrown (only) if the programmer could have prevented the exception before hand. This last point is arguable, but as a rule of thumb, works pretty well.

Checked exceptions should be used when a condition might occure, outside the programmers control, that isn’t what a typical work-flow would expect.  Check exceptions, if they can’t be dealt with, should bubble up to a user in an appropriate way.  The user should then be given an opportunity to decide what to do, such as retry the operation, report a bug, or go eat lunch and forget about it :-)

Now comes the interesting part. Circumventing checked exceptions.

There are at least two ways to throw a checked exception that isn’t actually checked.  Like with most of my esoteric Java features, they shouldn’t be used in production code. Both are hacks and both are ugly.

The first approach:  Class.newInstance().  Class.newInstance() will propagate any exceptions from the constructor to the calling code.  If your constructor throws a check exception, it will leak from Class.newInstance();

import java.io.IOException;
public class NoChecked1 {
   NoChecked1() throws IOException { throw new IOException("Leaked!"); }
   public static void main(String...args) {
      try {
          NoChecked1.class.newInstance();
      } catch (InstantiationException e) {
      } catch (IllegalAccessException e) {
      }
   }
}

The second approach: Thread.stop(Throwable t). stop(Throwable t) was deprecated a while ago, but Thank God Java Is Backward Compatible. calling this overload of stop will cause the thread to spontaneously throw an exception, checked or otherwise.

import java.io.IOException;
public class NoChecked1 {
   public static void main(String...args) {
      Thread.currentThread().stop(new IOException("Leaked again"));
   }
}

Yikes. Don’t try this at home kids.

Swing Concurrency

Saturday, February 9th, 2008

So many Java programmers get loured into the Swing trap. I’m not saying Swing is bad, but it has some pitfalls that many programmers fall into simply because they weren’t told otherwise.

The biggest pitfall is that most Swing classes are not thread safe, and there is a specific approach you must take to communicate with these classes.

Where there are many ways to approach thread-safety, the designers of Swing choose the “thread-partition” approach. What this means in simple terms is that any time you want to access data or methods in a Swing class, you should do it on a specific thread. This is much easier done than said.

Normally when you access an object, you use “ob.member”, for example: textField.setText("foo"). In Swing, you need to make sure your code gets called only from the Event Dispatch Thread (that’s the “single thread” as designated by Swing).

Communicating from any thread to Swing

In order to get your code to run on that thread, you can pass a Runnable to the java.awt.EventQueue. If you don’t know, Runnable is an interface in the standard Java API that has one method, public void run(); For example, in the above “foo” example, I could do this:

public void setFoo() {
   Runnable setFooRunnable = new Runnable() {
     public void run() {
       textField.setText("foo");
     }
  }
  EventQueue.invokeLater(setFooRunnable);
}

EventQueue.invokeLater tells the Event Dispatch Thread (EDT) to execute that code at its earliest convenience. invokeLater returns immediately, which may have consequences if you expect things to be done. There is another method that lets you wait until the EDT has completed your task, but it is strongly discouraged to use it.

There was a time in the past when Sun suggested that you could initialize your GUI outside of the EDT. They were wrong. Yes, I said it. Sun made a mistake. They have since sent out a correction, but unfortunately the harm was done and you’ll see some tutorials exemplifying this dangerous practice. If you so as much create an instance of a GUI object, do so on the EDT under bane of glitch. It may appear to work, but it will crash sometime, somewhere, and you might not ever hear about it from the customer who decided not to buy.

Don’t block the EDT, ever!

There is another consequence of this single thread approach. If you do something that takes a long time, and you do it on the EDT, you’ll make the whole application unresponsive. Most GUI’s, Swing included, are Event Driven, so instead of waiting for something, you should listen for that something. Most Swing components allow you to add listeners to them. The methods on your listeners get called when something they care about happens. This lets you avoid things like “while (!isFooRead()); doSomethingWithFoo(getFoo());” and instead you have “public void fooIsReady(Foo foo) { doSomethingWithFoo(foo); }“.

EDT is lazy, don’t give it hard work!

For the same reason you shouldn’t block the EDT, you should move time-consuming tasks (IO, calculations, etc…) off of the EDT. Every millisecond you take on the EDT is another millisecond that a mouse-click doesn’t get registered, or the window doesn’t repaint. This will give your program the appearance of being slow and unresponsive.

Java 1.6 has added a new class called SwingWorker that helps you pass work between a worker thread and the EDT in a clean and “correct” manor.

Where to go from here

Hopefully at this point you’ve learned the basics of what it takes to write a proper Swing program. From here, I suggest reading Concurrency in Swing from the Java tutorials. For a much more complete understanding of the why’s and how’s of Java concurrency, I suggest buying and reading Java Concurrency in Practice.

Sensitivity: A Case for Convention.

Monday, January 28th, 2008

Image this. You develop a Java application that uses only standard Java features. It only uses a hand full of classes, so you just distribute individually. It works great until someone using windows runs your program.

“Why am I getting ‘Exception in thread “main” java.lang.NoClassDefFoundError: FOO (wrong name: Foo)’?”
Remember, Java is case sensitive, but the Windows file system is *not*.

public class Foo {
  public static void main(String...args) {
    new FOO();
  }
}

class FOO {
  public FOO() {
    System.out.println("Works like a charm.");
  }
}

When you compile this on Linux, you get “Foo.class” and “FOO.class”, but on Windows, you only get one file. Oops!

So, its always a good idea to follow good convention with regards to capitalization. Use CamelCase, and treat abbreviations as words. Use XmlParser rather than XMLParser. Note that some of the standard Java API doesn’t do that (URL for instance).

Why is C so slow? Java vs. C benchmark.

Saturday, December 8th, 2007

Recently I’ve seen a few attacks on Java’s performance on comp.lang.java.programmer. So, I’ve decided to write my own benchmarks and test it myself. I expected the C version to perform slightly better, but at least in the same range, as the Java version. I was surprised that the Java version performed better, on both the client vm and the server vm.

I did my own benchmarks using these files:

bench.c

#include <stdio.h>
#include <time.h>

void bench() {
  long foo = 0;
  clock_t start = clock();
  for (long i = 1; i < 5000; ++i) {
    for (long j = 1; j < i; ++j) {
      if ((i % j) == 0) {
        foo ++;
      }
    }
  }
  clock_t end = clock();
  printf("%d %dms\n", foo,
     (int) ((end - start) * 1000 / CLOCKS_PER_SEC));
}

int main() {
  for (long i = 1; i < 10; ++i) {
    printf("%d: ", i);
    bench();
  }
}

Bench.java

public class Bench {
  static final long CLOCKS_PER_SEC = 1000;
  static void bench() {
    int foo = 0;
    long start = System.currentTimeMillis();
    for (int i = 1; i < 5000; ++i) {
      for (int j = 1; j < i; ++j) {
        if ((i % j) == 0) {
          foo ++;
        }
      }
    }
    long end = System.currentTimeMillis();
    System.out.printf("%d %dms\n", foo,
       (int) ((end - start) * 1000 / CLOCKS_PER_SEC));
  }

  public static void main(String[] args) {
    for (int i = 1; i < 10; ++i) {
      System.out.printf("%d: ", i);
      bench();
    }
  }
}

Then I ran these:

-bash-3.00$ java -version
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
-bash-3.00$ javac Bench.java
-bash-3.00$ g++ --version
g++ (GCC) 3.3.3 (NetBSD nb3 20040520)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-bash-3.00$ g++ bench.c -o bench

Now I’m ready to run the individual tests:

-bash-3.00$ java -server Bench
1: 38357 457ms
2: 38357 416ms
3: 38357 401ms
4: 38357 394ms
5: 38357 394ms
6: 38357 401ms
7: 38357 395ms
8: 38357 401ms
9: 38357 394ms
-bash-3.00$ java -client Bench
1: 38357 421ms
2: 38357 400ms
3: 38357 394ms
4: 38357 400ms
5: 38357 393ms
6: 38357 393ms
7: 38357 400ms
8: 38357 394ms
9: 38357 401ms
-bash-3.00$ ./bench
1: 38357 450ms
2: 38357 440ms
3: 38357 450ms
4: 38357 430ms
5: 38357 450ms
6: 38357 440ms
7: 38357 450ms
8: 38357 440ms
9: 38357 450ms

As you can see, the Java version is approximately 10% faster than the c version. So, here is my challenge. Why is C so slow? I thought it was supposed to be faster than Java.

More Discussion On Operator Overloading

Wednesday, December 5th, 2007

Updated: See notes below.

I was surprised to see that within one day of posting my previous entry on Operator Overloading, I received several comments. Aviad Ben Dov from Chaotic Java even took my idea and ran with it. Ricky Clarkson suggested using Haskell’s approach of allowing anything that is of the “Num” type to define +,-,/,*, etc…. I have a few things to add to this discussion.

Aviad’s idea for operators by interface is not a bad one; it works well for overloading “[]” but it breaks down on a few use cases (such as ‘+’, ‘*’, etc..) that are important (to me). Ricky’s idea for subtypes of a specific class getting to have operator overloading isn’t bad either, but for physical unit manipulation it is too inflexible. The core concept that both of them seem to have suggest is that a limited selection of types can have overloaded operators, but the operations that are possible aren’t limited to the scalar quantities that this would limit the operators to.

Suppose I have the classes Distance, Area, and the built-in “Scalar” type Double I would expect at least these sets of operations:
Distance * Distance => Area
Distance * Double => Distance

If I had to implement the Multipliable<T> interface, I wouldn’t be able to handle Distance * Distance and Distance * Double. You can’t implement an interface twice, even with different type parameters. I don’t know if this is something that Reified generics would fix, but it feels like it might be. Maybe someone could comment on that.

Also, if Distance had to extend Number, what would doubleValue return? Meters? Inches? Smoots? There might be some way to solve these problems, but I can’t think of a way to prevent abuse while allow good use.

Actually, now that I have thought a little about it…

The semantics of plus (+), minus (-), times (*), dividedBy (/), moduloOf (%), shiftLeft(<<), shiftRight(>>), unsignedShiftRight(>>>), or(|), and(&), xor (^), negative(-), and inverse(~), are all well-defined enough for so many not-necessarily-numeric types that allowing, even if only through naming conventions, the overloading of those operations seems like a good idea.

I think a good way to go would be to convert at compile time a * b to the method call a.times(b). Assignment operators like a += b would be replaced with a = a.plus(b). This would help reduce abuse while creating a more expressive language. The assignment operator rule is important, as it will help prevent the “clever” idiom of using += for appending elements to a collection.

Note on updates: I previously misspelled Aviad as “Avaid”. I also have added clarification for which use-cases Aviad’s Indexer doesn’t work for me, namely for algebraic operators.

Almost Useful: if instanceof

Friday, November 23rd, 2007

While often times if (x instanceof Y) indicates a problem that should be solved with proper use of polymorphic methods, it sometimes is unavoidable (.equals(Object o) implementation for example). A common idiom is:

if (x instanceof Y) {
  Y y = (Y) x;
}

Of course, this makes sense from a utility point of view, you know that it is a Y object, and so you want Y functionality from it. From a programmers point of view though, it is terribly redundant in many ways. In many cases, static analysis can tell the compiler that when you are in the block of that if statement, that x is indeed a Y object, why then should I be forced to cast to Y? Why can’t the compiler figure out the type for me?

This becomes even more useful if we combine the concept with the fully useful Type Intersection (Not yet implemented). If both of these features were implemented, then you could write something like:

public <T extends Comparable<T>> void sort(List<? extends T> list) {
 if (list instanceof RandomAccess) {
    /* list compile-time type here would be List<? extends T>&RandomAccess. */
    sort(list);
  } else {
    /* Other type of sort implementation. */
  }
}
public <T extends Comparable<T>> void sort(List<? extends T>&RandomAccess list) {
  /* Random access sort implementation */
}

This type of static analysis feature could be extended to predict NPE’s and redundant checks. Heck, the IDE I use tells me when I’ve accessed something when it might be null, or when my inner-if statement is a subset of the outer. It even has shortcuts for adding the cast in the if (x instanceof Y) {} blocks.

Almost Useful: Java Type Intersection.

Friday, November 23rd, 2007

First, for my subscribers that celebrate it, Happy Thanksgiving!

I’ve written about it before, but I think its worth revisiting. Type intersection would be a highly useful feature if not for one thing. “It is not possible to write an intersection type directly as part of a program; no syntax supports this.” – JLS (§4.9). That seems like a poor excuse to not support a feature as potentially powerful as type intersection could have been.

They were bold enough to add syntax all over the place for Generics. They added new syntatical meanings for ‘?’ ‘<’, and ‘>’. As a matter of fact, they added a syntax within that construct for handling Type Intersections. Would it really be that difficult to reuse that syntax outside of capture conversions and type inference? Heck, maybe even make it reifiable, although that’s not *as* important.

One example others have used in the past where it would be useful to have this type intersection is with the marker interface RandomAccess. While marker interfaces are less useful now that we have annotations, it none-the-less exists, and can be useful for ensuring that the user of an algorithm passes in a compatible list.

For example, its quite possible to do the following, even with the currently crippled implementation of type intersection.
<T extends List<String> & RandomAccess> void foo(T list) { ... }
You know that you’re getting a random access list. The pain point is that you can not do the following:
<T extends List<String> & RandomAccess> T foo() { return new ArrayList<String>(); }
The reason that isn’t legal is quite simple, even if its not obvious. T is any type that satisfies List<String>&RandomAccess, so you don’t know that it is an ArrayList. You might have MyNonArrayList<String> list = foo(); Oops, that would be an incompatible assignment.

The better approach would be to have the return type be an explicit type that is List<String>&RandomAccess. As a matter of fact, my suggestion is to use that syntax exactly, unless there is a compiler-grammar reason not to. So, our T foo() line becomes:
List<String>&RandomAccess foo() { return new ArrayList<String>(); }
So then we can do: List<String>&RandomAccess list = foo(); Actually, we could just use List<String> list=foo() if we don’t care about RandomAccess.

An important addition to make to this would be casting. For legacy support, if I have a List<String>, but I know that it should be an ArrayList (or some other RandomAccess), I should be able to cast: foo((List<String>&RandomAccess)list);

Primitive Obsession II: (Im)mutability and Redefining Primitive

Sunday, November 4th, 2007

Last week I discussed some of the techniques for and benefits of not using simple “Primitive” values to represent your data. This article is all about taking that concept to the next level.

Let’s say that I have a value that represents an angle. I could use a double to represent the radians, or I could create a class called Angle, which internally might use a double to represent radians. If you are trying to avoid primitive obsession, you would use the latter. Now you have value objects of type Angle which can be used in meaningful ways. So, we’re done, right? I say no.

Angle is now its own form of primitive. Just as an Integer object is an abstraction of a numeric value in a specific set of reals, an Angle instance is an abstraction of a geometric/trigonometric angle. This means that it can be the building block for other more specific types. For instance, a 2 dimensional vector can be represented in “polar form” as an Angle and a Magnitude. In a physical simulation, a Magnitude is often a Distance, so we’ll assume that case for this article.

So, we can create a Vector interface (not to be confused with the java.util.Vector class). We can then create a PolarVectorImpl class which uses Angle and Distance. We can even create a CartesianVectorImpl which uses two Distance objects to represent the vector. Whats more, is these can both be used by anything that expects a Vector, with no extra work in the client code. We can easily create a rotate(Angle) method, or any other useful methods.

Another important and related concept that we haven’t touched on is mutability. If an object is mutable, that means that the apparent state of the object can change over the lifetime of the object. If an object is immutable, the apparent state of the object will appear the same throughout the lifetime of the object. This means that any invocation of one method on that object will always have the same outcome as any other on that same method. Also, any object that is returned from those methods must either be immutable themselves, or be distinct instances. Why is this important? Immutable objects have some benefits.

  • Immutable objects are inherently thread safe.
  • Immutable objects are easy to reason about.
  • Immutable objects are easier to debug.
  • Immutable objects can be passed around freely without defensive copying.

On the down side, immutability makes a pretty boring universe. If you’re object is expected to do different things depending on what has happened to it in the past, that object must be mutable. It must have state.

What does this have to do with primitive values? Its common to create immutable value objects. If we design the Angle class to be immutable, then we can safely say that one instance represents exactly one angle throughout its lifetime. All of our Angle objects are value objects. They are utility objects and reusable in many projects. On the other hand, if we’re doing a simulation of sorts, it might be useful to have a mutable angle, something that we can adjust over time. Lets call this class Heading. What’s in a Heading? An Angle, of course. Now here’s where things get interesting…

Since an Angle is a measurable thing, its easy to compare two values for equality. For Angles specifically, they are equal if their values represent the same geometric angle. Once equality is established, those objects are equal for ever. Not so with Heading. A Heading may represent the same angle at one moment in time, but at another moment they represent very different angles. For this type of object, equality only makes sense for the identity. A Heading instance is its own object, and can be queried/manipulated by many other objects/methods within the project.

The benefit of this design, is a manipulator/querier need not know who “owns” the Heading instance. A Robot might have a Heading, and a SteeringServo might manipulate that Heading. You can create the Robot and the SteeringServo objects independently of each other. The SteeringServo doesn’t even need to know its the Heading of a Robot. Once the Robot and SteeringServo both have the same Heading instance, they become connected without being coupled. This is huge goal for Object Oriented designers/programmers. The correct functioning of a SteeringServo isn’t dependent on the correct functioning of a Robot, or even of a Heading, only on itself. Similarly, a Robot’s correct functioning isn’t dependent on the correct functioning of the SteeringServo. The program as a whole may not work if there is a bug, but it easier to look at one class and ask yourself “Is there anything wrong with this code,” than it is to ask the same question about the whole project.

If you think all of this abstraction is unnecessary or unhelpful, think about all the layers beneath our Heading class. Lets have some fun and break it down into its most primitive parts.

  • Heading instance is an identity value containing an Angle and representing a direction at a point in time.
  • An Angle is an equal-comparable value containing a double and representing a direction.
  • A double is a equal-comparable and order-comparable value containing an ordered set of bits and representing a real number.
  • A bit is an equal-comparable value containing a memory cell representing true or false.
  • A memory cell is often times a capacitor that is either charged or uncharged

If you had to think about the implementation details of a bit every time you used a double, it would make the mental weight of programming so immense that no useful programs could be written. Heading can now be used very easily without adding the mental weight of how its implemented. SteeringServo can be implemented without the mental weight of what it is steering. Overall, the practice of this kind of decoupling will make your program easier for the most important source-code interpreter. You.