March 23, 2007
I see that some people are not convinced that 'final' is a useful concept.  Allow me to illustrate an extremely common example from Java which might help clarify:

void databaseStuff(String sql)
{
    final PreparedStatement st = db_.prepareStatement(sql); try {
    st.setString(0, "foo"); // bind query param
    final ResultSet rs = st.getResultSet(); try {
    while (rs.next())
    {
        System.out.println(rs.getString(0));
    }
    } catch (Exception e) { rs.close(); }
    } catch (Exception e) { st.close(); }
}

Now, this is a fairly trivial example, but in the real world, this function would be 20x longer due to business logic.  In some cases, you might rebind st to a new query and requery the DB.  Or, you might rebind parameters and just get a new rs.  If the function is reasonably long, knowing whether or not st or rs has been rebound in the function significantly affects your understanding of the code, especially during debugging.

Being able to see that key values are 'final' eliminates a whole class of potential failure modes.  Note that you don't want these to be 'const'.  For instance, you want to bind your query params to st and iterate over the ResultSet.  However, you also want to know that only one query got executed, and that it only got run once for the observed variables.  That's useful information.  Hope that helps.

Dave