Monday, September 28, 2009

Groovy JDK (GDK): More File Fun

In previous blog posts covering features in the Groovy JDK (GDK), I have focused on the GDK's File.getText() method and on the GDK's File.deleteDir() method. In this blog post, I look at additional functionality provided by GDK's extended File such as File.readLines(), File.setText(), and File.size().

The File.readLines() method easily returns the text contents of a given file similarly to the File.getText() method, but it returns these contents as a List of Strings with each String representing individual lines in the read-in file.

The following code snippet, a Groovy script called fileReadLines.groovy, demonstrates this Groovy function:


file = new File("TextFile.txt")
lines = file.readLines()
printf "$file's contents: $lines%n"
for (line in lines) printf "\t$line%n"


As in the previous blog posting, TextFile.txt is defined as shown below:


This is a text file.
This is only a text file.


When the above Groovy script, fileReadLines.groovy, is executed with the above text file, the results are as shown in the next screen snapshot.



As this output demonstrates, the returned list's contents can be displayed implicitly with square brackets or it can be iterated over to print each element in the list one-by-one.

Groovy JDK (GDK) makes writing text to a file as easy as reading it. The File.setText(String) method works as easily as the File.getText() method as demonstrated in the code listing below.


file = new File("TextOutputFile.txt")
file.setText("I am text looking for home.")


The output from this is shown in the next screen snapshot.



The Javadoc-based documentation for File.setText(String) reports that this method is a synonym for File.write(String). Note that both of these methods completely overwrite any existing text in the given file. If one wants to append new text to a file without obliterating existing text, the File.append(Object) method is useful.



Finally, GDK's File.size() method can be useful to see the file's size. The following code listing shows it.


file = new File("TextOutputFile.txt")
file.setText("I am text looking for home.")
file.append("I am also looking for a good home.")
printf "Size of file TextOutputFile.txt: ${file.size()}%n"


The output from running the above is shown next.




Conclusion

This blog post has demonstrated how easy it is to use File.setText(String) (and File.write(String)), File.append(Object), File.readLines(), and File.size(). These extensions to the standard JDK File make manipulation of files easier for Groovy scripts.

Thursday, September 24, 2009

Groovy JDK (GDK): Text File to String

In my previous blog post, I briefly talked about the advantages of Groovy JDK (GDK) and specifically illustrated this by demonstrating how the GDK's File.deleteDir() method provides additional functionality beyond that provided by the standard SDK File.delete(). In this blog post, I demonstrate how another GDK extension function, File.getText(), makes extracting text from a file practically trivial.

When one wants to extract text from a file into a Java String, a typical approach is to use a BufferedReader. In fact, this is demonstrated in various forms in resources such as Java Developers Almanac 1.4 (swallows checked IOException), reading lines from text file, Reading and Writing Text Files, and How Do I Read a Text File? The How to Read File in Java example uses BufferedInputStream and DataInputStream.

In all of these examples, there is significant code involved to handle checked exceptions and resource management. Java-based one-line alternatives are discussed in the blog post Java One Liner - Reading a Text File at Once. Groovy, via its GDK, makes extracting a String from a File simple and convenient. The following Groovy code demonstrates how easy this is to use.

fileGetText.groovy

file = new File("TextFile.txt")
printf "$file's contents: ${file.getText()}"


The content of the TextFile.txt file is as shown next:

TextFile.txt

This is a text file.
This is only a text file.


The following screen snapshot shows the results of running the simple Groovy code against this text file:



All too easy!

Convenience methods such as File.getText() and File.deleteDir() make scripting with Groovy easier and more convenient.

Groovy JDK (GDK): File.deleteDir()

One of the many things that I like about Groovy is its Groovy JDK (also known as GDK). As the Groovy JDK API Specification states, the Groovy JDK provides "methods added to the JDK to make it more groovy." The Groovy JDK is a collection of extensions to classes available in the standard Java SDK such as Object. As a collection of extensions to the standard Java JDK, the Groovy JDK is separate and distinct from the Groovy API, which consists of classes unique to Groovy. In this blog post, I focus on one highly useful method the Groovy JDK adds to the standard java.io.File class for deleting a directory.

The standard Java JDK provides a File.delete() method that will delete files or directories. The Javadoc documentation for this method explicitly states that this method will not delete a directory that is not empty (contains other directories or files). The same Javadoc documentation also states that the boolean returned by this method will be true if and only if the directory is actually deleted. In other words, if the directory is not deleted because it does not exist or because it contains files or other directories, a false will be returned.

The Groovy JDK (GDK) provides an extension to the standard File class. The GDK File extension adds a method deleteDir() that behaves differently on directory deletion than the just-described behavior of the standard File.delete() method. In particular, the GDK File.deleteDir() will delete a directory even if it contains other files and directories (it deletes those contents as well, of course). This is kind of like the rm -rf in Linux and is particularly useful when one is certain he or she really wants to delete the directory no matter its contents. This is often the case when writing scripts.

Besides obediently removing a directory regardless of it containing files and other directories, the GDK File.deleteDir() method is also different from the standard File.delete() when acting on directories because it returns true both in situations in which a directory is successfully deleted and in situations in which the specified directory does not exist. On the other hand, false is returned when the directory does exist and cannot be deleted or when the File being acted upon is not actually a directory.

The following Groovy code can be used to illustrate the differences between the standard SDK File.delete() and the GDK File.deleteDir().

directoryDelete.groovy

directory = new File("dirToBeDeleted")
printf "Delete directory $directory with JDK File.delete(): ${directory.delete()}%n"
printf "Delete directory $directory with GDK File.deleteDir(): ${directory.deleteDir()}"


The next screen snapshot shows the results of executing the above Groovy code snippet. The snapshot shows that the "dirToBeDeleted" directory does exist and that it does have three .txt files in it.



The first attempt to delete this directory with files using File.delete() fails and returns false. However, the second attempt with the GDK File.deleteDir() is successful.

The next screen snapshot shows how both the standard File.delete() returns true when called on to remove an empty directory. Even with the directory now removed, the GDK File.deleteDir() also returns true.



Finally, we can see an example of when the Groovy JDK File.deleteDir() returns false. To make this happen, I changed the permissions of the "dirToBeDeleted" directory to not allow reading or writing. When I run the Groovy script against that locked-down directory, I see the following results:



The Groovy JDK (GDK) File.deleteDir() method is a useful extension that can make for easier and more convenient scripting that involves deletion of directories. This is just one of many "extension" methods that the GDK provides as enhancements to the functionality provided by the standard JDK.

Tuesday, September 22, 2009

You Might Be a Programmer If...

You might be a programmer/software developer/software engineer if...

1) you are primarily offended by the use of goto when someone tells you to go to Hell.

2) you know that Perl is not Pearl misspelled.

3) you don't think gems when you hear "Ruby."

4) you think programming language/platform when you hear the word "Java."

5) you know what a noop is.

6) you are aware of many different kinds of beans that have nothing to do with plants (JavaBeans, Enterprise JavaBeans, Spring beans, MBeans, NetBeans, etc.).

7) you refer to rearranging furniture or rearranging/cleaning your desk as "refactoring."

8) you are more comfortable writing code than writing prose.

9) you think the real bugs have nothing to do with insects or spiders.

10) you know that 10-9.9 is not necessarily equal to 0.1.



Related Links

⇒ You Might Be A Programmer If... (GNU)

⇒ You might be a programmer if... (Clay Shannon)

⇒ You Might Be a Programmer if... (maxabout.com)

Saturday, September 19, 2009

Is a Java Immutable Class Always final?

In response to my recent blog posting Immutable Java Objects, Matt brought up a good point of discussion related to making Java classes truly immutable by declaring them as final so that they cannot be extended. His comment was:

"Implementation inheritance explicitly disallowed." -- isn't this largely orthogonal to the question of immutability?


In that previously referenced blog post, I listed several resources that explain how to write immutable Java classes. Each of these resources recommends making the Java class final as one of the steps in making it immutable. The resources with the recommendation include Brian Goetz's To Mutate or Not to Mutate?, the Java Tutorial section on A Strategy for Designing Immutable Objects, and Joshua Bloch's Effective Java.

A similar question to this is asked in the StackOverflow thread immutable class should be final?: "So why is immutability a good reason for making a class final?" In this blog post, I look a little more deeply into this issue.

The CERT Secure Coding Standards contains the entry OBJ38-J. Immutable classes must prohibit extension which succinctly describes a primary rationale for specifying an immutable Java class as final:

By declaring immutable classes final, we impose a guarantee that malicious subclasses capable of changing the state of the object and violating assumptions that clients often make regarding immutability, are not a concern.


In Immutable Objects in Java, the four authors (Haack, Poll, Schafer, and Schubert) include a section on "enforcing immutability." In this section they maintain that classes which extend immutable classes must also themselves be immutable. The authors suggest that making the immutable class final would be one way to deal with a situation in which "malicious code may try to subclass an immutable class" and "masquerade" as its parent type,

In Mutable and Immutable Objects, David O'Meara specifies that there are two approaches for ensuring methods are not overridden in a class designed to be immutable. He differentiates between strong immutability (class is made final) and weak immutability (methods are individually and explicitly declared final rather than declaring class final). In O'Meara's words, "The preferred way is to make the class final" (strong immutability).

With the above background details in mind, it's time to move on to some code examples.

The following Fraction class has some traits of immutability (such as its fields being final and private):

Fraction.java

package dustin.examples;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
* Example of almost immutable class.
*/
public class Fraction
{
/** Fraction's numerator. */
private final long numerator;

/** Fraction's denominator. */
private final long denominator;

/** Scale used in BigDecimal division. */
private final int scale;

/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
*/
public Fraction(final long newNumerator, final long newDenominator)
{
this.numerator = newNumerator;
this.denominator = newDenominator;
this.scale = 25;
}

/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me along with a scale for my decimal representation.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
* @param newScale Scale of my decimal representation.
*/
public Fraction(final long newNumerator, final long newDenominator, final int newScale)
{
this.numerator = newNumerator;
this.denominator = newDenominator;
this.scale = newScale;
}

/**
* Provide this fraction's numerator.
*
* @return Numerator of this fraction.
*/
public long getNumerator()
{
return this.numerator;
}

/**
* Provide this fraction's denominator.
*
* @param Denominator of this fraction.
*/
public long getDenominator()
{
return this.denominator;
}

/**
* Provide double decimal representation of this fraction.
*
* @return Decimal (double) representation of this fraction.
*/
public double getDecimalRepresentation()
{
return (double) numerator / denominator;
}

/**
* Provide the BigDecimal representation of this fraction.
*
* @return BigDecimal representation of this fraction.
*/
public BigDecimal getBigDecimalRepresentation()
{
final BigDecimal bigNumerator = new BigDecimal(this.numerator);
final BigDecimal bigDenominator = new BigDecimal(this.denominator);
return bigNumerator.divide(bigDenominator, this.scale, RoundingMode.HALF_UP);
}

/**
* Provide String representation of this fraction.
*
* @return String representation of this fraction.
*/
public String getStringRepresentation()
{
return String.valueOf(this.numerator) + "/" + String.valueOf(this.denominator);
}

/**
* Provide String representation of this fraction.
*
* @return String representation of this fraction.
*/
@Override
public String toString()
{
return getStringRepresentation();
}

/**
* Main function testing this class.'
*
* @param arguments Command-line arguments; none expected.
*/
public static void main(final String[] arguments)
{
final Fraction fractionOne = new Fraction(2,3);
System.out.println("2 divided by 3 is " + fractionOne.getDecimalRepresentation());
System.out.println("2 divided by 3 is " + fractionOne.getBigDecimalRepresentation());
}
}


In the above example, neither the class nor its methods are declared as final. This allows a renegade subclass to be written as shown in the next class listing for RenegadeFraction.

RenegadeFraction.java

package dustin.examples;

import java.math.BigDecimal;

/**
* Class extending the 'immutable' Fraction class.
*/
public class RenegadeFraction extends Fraction
{
/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
*/
public RenegadeFraction(final int newNumerator, final int newDenominator)
{
super(newDenominator, newNumerator);
}

/**
* Provide double decimal representation of this fraction.
*
* @return Decimal (double) representation of this fraction.
*/
public double getDecimalRepresentation()
{
return 6.0;
}

/**
* Provide the BigDecimal representation of this fraction.
*
* @return BigDecimal representation of this fraction.
*/
public BigDecimal getBigDecimalRepresentation()
{
return new BigDecimal(5.0);
}

/**
* Provide String representation of me.
*
* @return My String representation.
*/
@Override
public String toString()
{
return
"Fraction with numerator " + getNumerator() + " and denominator "
+ getDenominator();
}
}


Because the parent Fraction class is not final and its method are not final, the RenegadeFraction class is able to override its methods and return nonsensical results. Note that even if we made the main methods final, the constructor of RenegadeFraction could still intentionally or accidentally swap the constructor arguments passed to its parent class.

This example also shows a misbehaving toString() implementation in the subclass. If we extend the Fraction class and mark the methods we don't want overridden with final, there could be confusing issues surrounding "other" methods like toString(). Do we want to make toString() final or allow the child class to potentially misrepresent its (and its parent's) real contents?

The next code listing demonstrates how a child class can misrepresent its parents to clients. The main code here believes it is dealing with Fraction class and may even make some assumptions based on that. The actual instance passed to the client is the RenegadeFraction resulting from intentional abuse or from careless development.

DemonstrationMain.java

package dustin.examples;

import java.math.BigDecimal;
import static java.lang.System.out;

/**
* Demonstrate how allowing an immutable class to be extended can reduce
* immutability, at least from the perspective of its behavior.
*/
public class DemonstrationMain
{
/**
* Enumeration representing type of fraction to help in readability of output.
*
* This differentiates between the original Fraction and the extending class
* RenegadeFraction.
*/
public enum FractionType
{
FRACTION("Fraction"),
RENEGADE_FRACTION("Renegade");

private String stringRepresentation;

FractionType(final String newStringRepresentation)
{
this.stringRepresentation = newStringRepresentation;
}

public String getStringRepresentation()
{
return this.stringRepresentation;
}
}

/**
* Accepts immutable Fraction object and prints its String value.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionToString(final Fraction fraction, final FractionType type)
{
out.println("Fraction [" + type.getStringRepresentation() + "] is " + fraction);
}

/**
* Accepts immutable Fraction object and prints its String value.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionStringRepresentation(
final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] is "
+ fraction.getStringRepresentation());
}

/**
* Accepts immutable Fraction object and prints its decimal representation.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionDecimalValue(final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] decimal: "
+ fraction.getDecimalRepresentation());
}

/**
* Accepts immutable Fraction object and prints its BigDecimal representation.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionBigDecimalValue(final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] BigDecimal: "
+ fraction.getBigDecimalRepresentation());
}

/**
* Print quotient resulting from division of provided dividend by provided
* divisor.
*
* @param dividend Dividend in division.
* @param divisor Divisor in division.
*/
public static void printExternalDivisionResults(
final BigDecimal dividend, final BigDecimal divisor)
{
out.println(
"Division of dividend " + dividend + " by divisor " + divisor
+ " leads to quotient of " + dividend.divide(divisor));
}

/**
* Main function for executing immutable object or child of immutable object.
*
* @param arguments Command-line arguments; none expected;
*/
public static void main(final String[] arguments)
{
final Fraction fraction = new Fraction(2,3);
final RenegadeFraction renegadeFraction = new RenegadeFraction(2,3);

printFractionToString(fraction, FractionType.FRACTION);
printFractionToString(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionStringRepresentation(fraction, FractionType.FRACTION);
printFractionStringRepresentation(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionDecimalValue(fraction, FractionType.FRACTION);
printFractionDecimalValue(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionBigDecimalValue(fraction, FractionType.FRACTION);
printFractionBigDecimalValue(fraction, FractionType.RENEGADE_FRACTION);

printExternalDivisionResults(
new RenegadeBigDecimal(fraction.getNumerator()),
new RenegadeBigDecimal(fraction.getDenominator()));
printExternalDivisionResults(
new RenegadeBigDecimal(renegadeFraction.getNumerator()),
new RenegadeBigDecimal(renegadeFraction.getDenominator()));
}
}


When the above demonstration class is executed, its output appears as shown below:



The output shown above demonstrates how a subclass can misrepresent its parent's advertised behavior. This can happen anytime implementation inheritance is involved, but it is more insidious when we have reason to believe the class involved is immutable. We could mark the methods as final to reduce much of this, but the constructor still has issues. Furthermore, marking all the parent class's methods as final rather than simply marking the entire class as final has some drawbacks. These include the potential conundrum about how to handle methods (such as toString()) that really should not be final and the risk of new methods being added to the parent class without the developer remembering or knowing to mark them as final.

In the DemonstrationMain class, I also made use of a custom class called RenegadeBigDecimal. The purpose of this class is to demonstrate the abuse of a subclass of BigDecimal. The code listing for RenegadeBigDecimal is shown next.

RenegadeBigDecimal.java

package dustin.examples;

import java.math.BigDecimal;

/**
* Demonstrating the troubles with non-final 'immutable' classes.
*/
public class RenegadeBigDecimal extends BigDecimal
{
/**
* Parameterized constructor accepting Long for instantiation of BigDecimal.
*
* @param val Long parameter intended, but not actually used, for
* instantiation of BigDecimal.
*/
public RenegadeBigDecimal(final Long val)
{
super(-1);
}

/**
* Example of intentionally abusing behavior likely expected for an
* immutable class by the subclass.
*
* @param divisor Divisor in division process.
*/
public BigDecimal divide(final BigDecimal divisor)
{
return this;
}
}


This last example shows how easy it is to abuse BigDecimal. Because the divide method was overridden to return itself, it is obvious that neither the BigDecimal class nor its method divide were designated as final. Even if the divide method would have been made final, the constructor could still have implemented bad intent and any client code thinking it was a BigDecimal would pay the consequences.


Trade-offs and Drawbacks of final Immutable Classes

There may be times when the ability to override a "largely immutable" or "mostly immutable" class is more important than having a "completely immutable" or "strongly immutable" class. Software design and development is full of trade-offs and this is just another one of those. The benefits of different degrees of mutability can be weighed against the costs. I believe it is no coincidence that Joshua Bloch changed the title of his Effective Java item on immutable objects from "Favor Immutability" in Edition 1 to "Minimize Mutability" in Edition 2. I think this is most readily done by starting with a class that is completely or strongly immutable and only relaxing its mutability in different ways when justified by the benefits of doing so.

Again, at least in my mind, it is no coincidence that the creators of the recently announced Noop project have stated that they wish to encourage immutability and that they wish to discourage implementation inheritance. I think in many of the cases in which implementation inheritance might be desired, it might be better to simply use composition to share common, immutable data and behaviors between two highly related, possibly immutable, classes. That advice doesn't sound particularly different than what many others have suggested before in terms of all classes, including mutable classes.


Conclusion

The safest way to make a class "strongly immutable" is to designate the entire class as final. Doing so ensures that no mistakes will be made in creating new methods in the future in the immutable class that are not marked final and can be carelessly or maliciously overridden. The final keyword applied at class level also prevents subclasses from "masquerading" as their immutable parent with very different behavior than that expected for the "immutable" parent class.



Additional References

⇒ Mutable and Immutable Objects

⇒ Making a Class Immutable

⇒ StackOverflow: immutable class should be final?

⇒ OBJ38-J: Immutable Classes Must Prohibit Extension

⇒ Bug 4617197 - RFE: Add Immutable types to Java

⇒ Immutable Objects in Java

⇒ Some Concurrency Tips (talks about benefits of immutable objects)

⇒ The Final Word on the final Keyword

Friday, September 18, 2009

Noop: Google's Language for the JVM

Perhaps the biggest news at the JVM Language Summit was the formal announcement of Google's Noop programming language for the Java Virtual Machine. Opinionated software and JVM languages are all the rage these days and Noop appears to be both. The main Noop project page states that "Noop's got an attitude" (another way to say it's opinionated) and the project's subtitle highlights its JVM nature and focus on testability: "A testable programming language running on the JVM."

I have find that I generally like opinionated software when its creators share the same opinions that I have and dislike opinionated software when its creators have strongly different opinions than I have. This is not a surprising observation, but it is a reminder that I should probably generally agree with the opinions that form a language's or framework's foundation and vision before jumping earnestly into that language or framework.

Noop's Opinions

As the project's subtitle ("A testable programming language running on the JVM.") suggests, testability is a primary objective in the design of the Noop language. Thus it is not surprising that many of the opinions behind Noop are related to language features that tend to make code testing easier. Major features that Noop is designed to strongly encourage include testability, dependency injection, readability, strong typing, and immutability. On the other side, Noop attempts to deter use of statics (often cited as problematic for testing), implementation inheritance, primitives, and boilerplate code.

Even the project's main page is highly opinionated. Take, for example, this description of dependency injection (I added the highlight):

Dependency Injection changed the way we write software. Spring overtook EJB's in thoughtful enterprises, and Guice and PicoContainer are an important part of many well-written applications today.


It is difficult to quantify the "thoughtful enterprises," though it is at least implied that those who use Enterprise JavaBeans (does this include EJB3/JEE5/JEE6?) are not as thoughtful.


Conclusion

We seem to be seeing more JVM-based languages coming out all the time. Most will probably never gain significant traction and be lost in the noise, but it will be interesting to see if Google-backed Noop can begin to compete with other JVM-based languages such as Groovy, JRuby, Jython, Scala, and other leading contenders for developer mind share.


Additional Resources

⇒ noop: A Testable Programming Language Running on the JVM

⇒ Google Urges Developers to Get in Loop with Noop

⇒ Google Launches 'Noop' Language for the Java Platform

⇒ Noop: A New JVM Language by Google

⇒ Google Delivers New Java-like Language: Noop

⇒ Google's Noop Steals the Show at the JVM Language Summit

⇒ Google Develops 'Noop' Language

Tuesday, September 15, 2009

Immutable Java Objects

Immutable objects are highly desirable. Because an immutable object's state cannot be changed, they are particularly useful in concurrent environments. Immutable options can simplify code and reduce chances of unanticipated and undesired state in objects.

I prefer that all of my Java classes provide for immutable objects unless there is a compelling need for them to be mutable. I'm not the only one who feels this way. In Effective Java (Item 15 ["Minimize Mutability"] in the Second Edition and Item 13 ["Favor Immutability"] in the First Edition), Joshua Bloch extols the virtues of immutable objects and emphasizes in bold text:

Classes should be immutable unless there's a very good reason to make them mutable.


Another proponent of immutable objects is Martin Odersky of Scala fame. He has stated about immutable objects:

we recommend that if you can make [objects] immutable, that's good, and you should try to find out where you can make objects immutable.


Conceptually, it sounds easy to create immutable objects. However, there are a couple nuances to note when ensuring that a Java class is defined so that its instantiated objects are immutable. Several resources outline the steps necessary to write a Java class that will lead to immutable Java objects. These resources include the previously mentioned Joshua Bloch Effective Java items on immutable objects. Other resources outlining the steps for making a Java object immutable include Java Practices, the Java Tutorials, JavaWorld's article Mutable or Immutable?, and developerWorks's To Mutate or Not to Mutate?.

Java classes that support immutable objects have the following characteristics:

• No "set" or mutator methods (object's state is set at instantiation/construction and cannot be changed later).

• Implementation inheritance explicitly disallowed.

• Fields are final and private.

• Its data members are either immutable or only provides access to defensive copies (also covered in Effective Java) of its mutable members.



As threading becomes more significant, immutable objects become more important. Trendy languages such as Scala and Clojure emphasize the importance of immutable data structures and immutable objects in their very design.

I have found that it works best for me to start with my objects as immutable objects and then only relax the immutability as absolutely necessary. This minimizes the mutability when it is required. In general, I resist the urge to "easily" use the IDE feature that quickly and thoughtlessly creates getter and setter methods for my new classes. I have found that it is better to think about how the class is used and only provide the mutability that is absolutely necessary.