Showing posts with label immutable objects. Show all posts
Showing posts with label immutable objects. Show all posts

Sunday, 20 February 2011

Returning immutable collections

Many times it is desirable to return an internal collection object to consumers of your class.

For example:

class Foo {
List _internalObjects = new ArrayList();

List getList() {
return _internalObjects;
}
}


The method above works, but has a draw back. The elements of your internalObjects list are now mutable outside your control. In C++ you might try to return const& instead to get around this problem, but how do you solve this in Java?

The first approach might be to return a copy. e.g:
class Foo {
List _internalObjects = new ArrayList();

List getList() {
List copy = new ArrayList();
copy.addAll(_internalObjects);
return copy;
}
}


This has the desired effect but with a couple of disadvantages. First you had to perform the copy which could be a performance bottleneck. Second the consumer may no longer point to the same objects if you modify your internalObject class.

The best way, that I know of, to do this is as follows:

class Foo {
final List _internalObjects = new ArrayList();

List getList() {

return new AbstractList() {
@Override
public Object get(int index)
{
return _internalObjects.get(index);
}
@Override
public int size()
{
return _internalObjects.size();
}
};
}
}


The returned list still points to internal list, but is read only. Also, just to be pedantic, I've marked the list as final which means the reference will never change which is more correct for this example.

Tuesday, 15 February 2011

Immutable objects

Immutable objects are simply objects whose state (the object's data) cannot change after construction. Examples of immutable objects from the JDK include String and Integer.
Immutable objects greatly simplify your program, since they :
  • are simple to construct, test, and use
  • are automatically thread-safe and have no synchronization issues
  • do not need a copy constructor
  • do not need an implementation of clone
  • allow hashCode to use lazy initialization, and to cache its return value
  • do not need to be copied defensively when used as a field
  • make good Map keys and Set elements (these objects must not change state while in the collection)
  • have their class invariant established once upon construction, and it never needs to be checked again
  • always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state
Immutable objects have a very compelling list of positive qualities. Without question, they are among the simplest and most robust kinds of classes you can possibly build. When you create immutable classes, entire categories of problems simply disappear.Make a class immutable by following these guidelines :
  • ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
  • make fields private and final
  • force callers to construct an object completely in a single step, instead of using a no-argument constructor combined with subsequent calls to setXXX methods (that is, avoid the Java Beans convention)
  • do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state
  • if the class has any mutable object fields, then they must be defensively copied when passed between the class and its caller
In Effective Java, Joshua Bloch makes this compelling recommendation :"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."
It's interesting to note that BigDecimal is technically not immutable, since it's not final.
Example
import java.util.Date;

/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/

public final class Planet {

public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}

/**
* Returns a primitive value.
*
* The caller can do whatever they want with the return value, without
* affecting the internals of this class. Why? Because this is a primitive
* value. The caller sees its "own" double that simply has the
* same value as fMass.
*/

public double getMass() {
return fMass;
}

/**
* Returns an immutable object.
*
* The caller gets a direct reference to the internal field. But this is not
* dangerous, since String is immutable and cannot be changed.
*/

public String getName() {
return fName;
}

// /**
// * Returns a mutable object - likely bad style.
// *
// * The caller gets a direct reference to the internal field. This is usually dangerous,
// * since the Date object state can be changed both by this class and its caller.
// * That is, this class is no longer in complete control of fDate.
// */
// public Date getDateOfDiscovery() {
// return fDateOfDiscovery;
// }

/**
* Returns a mutable object - good style.
*
* Returns a defensive copy of the field.
* The caller of this method can do anything they want with the
* returned Date object, without affecting the internals of this
* class in any way. Why? Because they do not have a reference to
* fDate. Rather, they are playing with a second Date that initially has the
* same data as fDate.
*/

public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}

// PRIVATE //

/**
* Final primitive data is always immutable.
*/

private final double fMass;

/**
* An immutable object field. (String objects never change state.)
*/

private final String fName;

/**
* A mutable object field. In this case, the state of this mutable field
* is to be changed only by this class. (In other cases, it makes perfect
* sense to allow the state of a field to be changed outside the native
* class; this is the case when a field acts as a "pointer" to an object
* created elsewhere.)
*/

private final Date fDateOfDiscovery;
}



Note that javadoc 1.4 includes the -tag option, whereby simple custom tags may be defined. One might define an@is.Immutable tag, for example, to document a class as being immutable.You might also consider defining your own tag interface for immutable objects.

Wednesday, 28 July 2010

Final keyword in java

A java variable can be declared using the keyword final. Then the final variable can be assigned only once. You cannot be modify it afterwards. However it can be used in different contexts.

Following are the places where final can be used:

  1. variables: a final variable can be set once and only once.
    blank final variable - A variable that is declared as final and not initialized is called a blank final variable. A blank final variable forces the constructors to initialise it.
  2. fields: a final field can also be set only once, by the constructor of the class which defines it.
  3. methods: a final method cannot be overridden nor hidden.
    final parameters - values of the parameters cannot be changed after initialization.
  4. classes: a final class cannot be extended or inherited.

Other effects of final:

  • Java local classes can only reference local variables and parameters that are declared as final.
  • A visible advantage of declaring a java variable as static final is, the compiled java class results in faster performance.

Notice how using final is an entirely negative act. The final keyword works by subtracting, limiting default language mechanisms: the ability to override a method, to set a variable or a field. The motivations behind using final fall into three broad categories: correctness, robustness, and finally performance. Seeing them 1 by one.

Final Variables

Final variables come in handy in mostly three situations: 

a) Declare Constants

Coupled with static, final is used to flag constants. This usage is well-known to all Java programmers, so I won't expand much on it. It is useful to know that the value of a field declared constant in that manner will be computed statically if possible, at compile-time.
private static final int ERROR_CODE = 1 + 3 * 4 / 2;
public static final String ERROR_MESSAGE = "An error
occurred with code="
+ ERROR_CODE;

The compiler will compute the value for ERROR_CODE, concatenate the string equivalent of the result, and assign the resulting String to ERROR_MESSAGE.


b) Final Parameters

The following sample declares final parameters:




public void doSomething(final int i, final int j){
// ...
}
final is used here to ensure the two indexes i and j won't accidentally be reset by the method. It's a handy way to protect against an insidious bug that erroneously changes the value of your parameters. Generally speaking, short methods are a better way to protect from this class of errors, but final parameters can be a useful addition to your coding style.
Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.


c) Anonymous Local Classes

The third situation involving final variables is actually mandated by language semantics. In that situation, the Java compiler won't let you use a variable unless it is declared final. This situation arises with closures, also known as anonymous local classes. Local classes can only reference local variables and parameters that are declared final.





public void doSomething(int i, int j){
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};//note the semicolon here
}

The reason for this restriction becomes apparent if we shed some light on how local classes are implemented. An anonymous local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee in place, the local class is assured that its internal copies of the variables accurately reflect the actual local variables.


2. Final Fields

A final field can be assigned once and only once, and must be initialized by every constructor of the class that declares it. It is also possible to assign the field directly, in the same statement where it is defined. This simply reflects the fact that such shortcut assignments are compiled into a synthetic constructor. E.g. both the following code samples are correct and strictly equivalent; the first is preferred for being shorter. Initializing outside constructor body

public class MyClass{
//initializing hereitself
private final int i = 2;
}

Initialising in constructor body



public class MyClass{
private final int i;
public MyClass()
{
i = 2;
}
}


3. Using final to Prevent Method Overriding



While method overriding is one of Java’s most powerful features, there will be times when you will want to prevent it from occurring. To disallow a method from being overridden, specify final as a modifier at the start of its declaration. Methods declared as final cannot be overridden. The following fragment illustrates final:


class A {

final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {

void meth() { // ERROR! Can't override.
System.out.println("Illegal!");
}
}

Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to
do so, a compile-time error will result.

Methods declared as final can sometimes provide a performance enhancement: The compiler is free to inline calls to them because it “knows” they will not be overridden by a subclass. When a small final method is called, often the Java compiler can copy the bytecode for the subroutine directly inline with the compiled code of the calling method, thus eliminating the costly overhead associated with a method call. Inlining is only an option with final methods. Normally, Java resolves calls to methods dynamically, at run
time. This is called late binding. However, since final methods cannot be overridden, a call to one can be resolved at compile time. This is called early binding.



4. Using final to Prevent Inheritance

Sometimes you will want to prevent a class from being inherited. To do this, precede the class declaration with final. Declaring a class as final implicitly declares all of its methods as final, too. As you might expect, it is illegal to declare a class as both abstract and final since an abstract class is incomplete by itself and relies upon its subclasses to provide complete implementations.
Here is an example of a final class:
final class A {
// ...
}
// The following class is illegal.
class B extends A { // ERROR! Can't subclass A
// ...
}


As the comments imply, it is illegal for B to inherit A since A is declared as final.


CPP vs Java on Final – Controversy


‘final’ should not be called as constants. Because when an array is declared as final, the state of the object stored in the array can be modified. You need to make it immutable in order not to allow modifcations. In general context constants will not allow to modify. In C++, an array declared as const will not allow the above scenario but java allows. So java’s final is not the general constant used across in computer languages.

A variable that is declared static final is closer to constants in general software terminology. You must instantiate the variable when you declare it static final.

Definition as per java language specification (third edition) – 4.12.4 is “A final variable may only be assigned to once.”(§4.1.2). See notes on final w.r.t Java memory model here -


Java language specification tries to redefine the meaning of constant in the following way!
We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).


Immutable Objects


Final is used to construct immutable objects in java. See – Immutable Objects