Archive for the ‘Generics’ Category

In my last article I showed two different ways to read/write persistent entity state – field and property. When field access mode is used, JPA directly reads the state values from the fields of an entity using reflection. It directly translates the field names into database column names if we do not specify the column names explicitly.  In case of property access mode, the getter/setter methods are used to read/write the state values. In this case we annotate the getter methods of the entity states instead of the fields using the same annotations. If we do not explicitly specify the database column names then they are determined following the JavaBean convention, that is by removing the “get” portion from the getter method name and converting the first letter of the rest of the method name to lowercase character.

We can specify which access mode to use for an entity by using the @Access annotation in the entity class declaration. This annotation takes an argument of type AccessType (defined in the javax.persistence package) enum, which has two different values corresponding to two different access modes – FIELD and PROPERTY. As an example, we can specify property access mode for the Address entity in the following way –

@Entity
@Table(name = "tbl_address")
@Access(AccessType.PROPERTY)
public class Address {
  private Integer id;
  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  @Id
  @GeneratedValue
  @Column(name = "address_id")
  public Integer getId() {
    return id;
  }

  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  public String getStreet() {
    return street;
  }

  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  public String getCity() {
    return city;
  }

  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  public String getProvince() {
    return province;
  }

  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  public String getCountry() {
    return country;
  }

  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  public String getPostcode() {
    return postcode;
  }

  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

Couple of points to note about the above example –

  1. As discussed before, we are now annotating the getter method of the entity id with the @Id@GeneratedValue and @Column annotations.
  2. Since now column names will be determined by parsing the getter methods, we do not need to mark the transientColumn field with the @Transient annotation anymore. However if Address entity had any other method whose name started with “get”, then we needed to apply @Transient on it.

If an entity has no explicit access mode information, just like our Address entity that we created in the first part of this series, then JPA assumes a default access mode. This assumption is not made at random. Instead, JPA first tries to figure out the location of the @Id annotation. If the @Id annotation is used on a field, then field access mode is assumed. If the @Id annotation is used on a getter method, then property access mode is assumed. So even if we remove the @Access annotation from the Address entity in the above example the mapping will still be valid and JPA will assume property access mode –

@Entity
@Table(name = "tbl_address")
public class Address {
  private Integer id;
  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  @Id
  @GeneratedValue
  @Column(name = "address_id")
  public Integer getId() {
    return id;
  }

  // Rest of the class........
  

Some important points to remember about the access modes –

  1. You should never declare a field as public if you use field access mode. All fields of the entity should have either private (best!), protected or default access type. The reason behind this is that declaring the fields as public will allow any unprotected class to directly access the entity states which could defeat the provider implementation easily. For example, suppose that you have an entity whose fields are all public. Now if this entity is a managed entity (which means it has been saved into the database) and any other class changes the value of its id, and then you try to save the changes back to the database, you may face unpredictable behaviors (I will try to elaborate on this topic in a future article). Even the entity class itself should only manipulate the fields directly during initialization (i.e., inside the constructors).
  2. In case of property access mode, if we apply the annotations on the setter methods rather than on the getter methods, then they will simply be ignored.

It’s also possible to mix both of these access types. Suppose that you want to use field access mode for all but one state of an entity, and for that one remaining state you would like to use property access mode because you want to perform some conversion before writing/after reading the state value to and from the database. You can do this easily by following the steps below –

  1. Mark the entity with the @Access annotation and specify AccessType.FIELD as the access mode for all the fields.
  2. Mark the field for which you do not like to use the field access mode with the @Transient annotation.
  3. Mark the getter method of the property with the @Access annotation and specify AccessType.PROPERTY as the access mode.

The following example demonstrates this approach as the postcode has been changed to use property access mode –

@Entity
@Table(name = "tbl_address")
@Access(AccessType.FIELD)
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
 
  /**
    * postcode is now marked as Transient
    */
  @Transient
  private String postcode;
 
  @Transient
  private String transientColumn;

  public Integer getId() {
    return id;
  }

  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  public String getStreet() {
    return street;
  }

  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  public String getCity() {
    return city;
  }

  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  public String getProvince() {
    return province;
  }

  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  public String getCountry() {
    return country;
  }

  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  /**
    * We are now using property access mode for reading/writing
    * postcode
    */
  @Access(AccessType.PROPERTY)
  public String getPostcode() {
    return postcode;
  }

  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

The important thing to note here is that if we do not annotate the class with the @Access annotation to explicitly specify the field access mode as the default one, and we annotate both the fields and the getter methods, then the resultant behavior of the mapping will be undefined. Which means the outcome will totally depend on the persistence provider i.e., one provider might choose to use the field access mode as default, one might use property access mode, or one might decide to throw an exception!

That’s it for today. If you find any problems/have any questions, please do not hesitate to comment!

Until next time.

Resources

  1. Pro JPA 2 by Mike Keith, Merrick Schincariol
  2. Java Persistence WikiBook
Advertisements

In my last post I showed a simple way of persisting an entity. I explained the default approach that JPA uses to determine the default table for an entity. Let’s assume that we want to override this default name. We may like to do so because the data model has been designed and fixed before and the table names do not match with our class names (I have seen people to create tables with “tbl_” prefix, for example). So how should we override the default table names to match the existing data model?

Turns out, it’s pretty simple. If we need to override the default table names assumed by JPA, then there are a couple of ways to do it –

  1. We can use the name attribute of the @Entity annotation to provide an explicit entity name to match with the database table name. For our example we could have used @Entity(name = “tbl_address”) in our Address class if our table name was tbl_address.
  2. We can use a @Table (defined in the javax.persistence package) annotation just below the @Entity annotation and use its name attribute to specify the table name explicitly –
@Entity
@Table(name = "tbl_address")
public class Address {
  // Rest of the class
}

From these two approaches the @Table annotation provides more options to customize the mapping. For example, some databases like PostgreSQL have a concept of schemas, using which you can further categorize/group your tables. Because of this feature you can create two tables with the same name in a single database (although they will belong to two different schemas). To access these tables you then add the schema name as the table prefix in your query. So if a PostgreSQL database has two different schemas named public (which is sort of like default schema for a PostgreSQL database) and document, and both of these schemas contain tables named document_collection, then both of these two queries are perfectly valid –

-- fetch from the table under public schema
SELECT *
FROM   public.document_collection;

-- fetch from the table under document schema
SELECT *
FROM   document.document_collection;

In order to map an entity to the document_collection table in the document schema, you will then use the @Table annotation with its schema attribute set to document

@Entity
@Table(name="document_collection", schema="document")
public class DocumentCollection {
  // rest of the class
}

When specified this way, the schema name will be added as a prefix to the table name when the JPA goes to the database to access the table, just like we did in our queries.

What if rather than specifying the schema name in the @Table annotation you append the schema name in the table name itself, like this –

@Entity
@Table(name = "document.document_collection")
public class DocumentCollection {
  // rest of the class
}

Inlining the schema name with the table name this way is not guaranteed to work across all JPA implementations because support for this is not specified in the JPA specification (non-standard). So it’s better if you do not make a habit of doing this even if your persistence provider supports it.

Let’s turn our attention to the columns next. In order to determine the default columns, JPA does something similar to the following –

  1. At first it checks to see if any explicit column mapping information is given. If no column mapping information is found, it tries to guess the default values for columns.
  2. To determine the default values, JPA needs to know the access type of the entity states i.e., the way to read/write the states of the entity. In JPA two different access types are possible – field and property. For our example we have used the field access (actually JPA assumed this from the location/placement of the @Id annotation,  but more on this later). If you use this access type then states will be written/read directly from the entity fields using the Reflection API.
  3. After the access type is known, JPA then tries to determine the column names. For field access type JPA directly treats the field name as the column names, which means if an entity has a field named status then it will be mapped to a column named status.

At this point it should be clear to us how the states of the Address entities got saved into the corresponding columns. Each of the fields of the Address entity has an equivalent column in the database table tbl_address, so JPA directly saved them into their corresponding columns. The id field was saved into the id column, city field into the city column and so on.

OK then, let’s move on to overriding column names. As far as I know there is only one way (if you happen to know of any other way please comment in!) to override the default column names for entity states, which is by using the @Column (defined in the javax.persistence package) annotation. So if the id column of the tbl_address table is renamed to be address_id then we could either change our field name to address_id, or we could use the @Column annotation with its name attribute set to address_id

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  // Rest of the class
}

You can see that for all the above cases the default approaches that JPA uses are quite sensible, and most of the cases you will be happy with it. However, changing the default values are also very easy and can be done very quickly.

What if we have a field in the Address entity that we do not wish to save in the database? Suppose that the Address entity has a column named transientColumn which does not have any corresponding default column in the database table –

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  // Rest of the class
}

If you compile your code with the above change then you will get an exception which looks something like below –

Exception in thread “main” java.lang.ExceptionInInitializerError
at com.keertimaan.javasamples.jpaexample.Main.main(Main.java:33)
Caused by: javax.persistence.PersistenceException: Unable to build entity manager factory
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:83)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<init>(PersistenceManager.java:31)
at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<clinit>(PersistenceManager.java:26)
… 1 more
Caused by: org.hibernate.HibernateException: Missing column: transientColumn in jpa_example.tbl_address
at org.hibernate.mapping.Table.validateColumns(Table.java:365)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1336)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75)
… 6 more

The exception is saying that the persistence provider could not find any column in the database whose name is transientColumn, and we did not do anything to make it clear to the persistence provider that we do not wish to save this field in the database. The persistence provider took it as any other fields in the entity which are mapped to database columns.

In order to fix this problem, we can do any of the following –

  1. We can annotate the transientColumn field with the @Transient (defined in javax.persistence package) annotation to let the persistence provider know that we do not wish to save this field, and it does not have any corresponding column in the table.
  2. We can use the transient keyword that Java has by default.

The difference between these two approaches that comes to my mind is that, if we use the transient keyword instead of the annotation, then if one of the Address entities gets serialized from one JVM to another then the transientColumn field will get reinitialized again (just like any other transient fields in Java). For the annotation, this will not happen and the transientColumn field will retain its value across the serialization. As a rule of thumb, I always use the annotation if I do not need to worry about serialization (and in most of the cases I don’t).

So using the annotation, we can fix the problem right away –

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;

  @Transient
  private String transientColumn;

  // Rest of the class
}

So that’s it for today folks. If you find any mistakes/have any input, please feel free to comment in!

Until next time.

This is a continuation of an introductory discussion on Generics, previous parts of which can be found here.

In the last article we were discussing about recursive bounds on type parameters. We saw how recursive bound helped us to reuse the vehicle comparison logic. At the end of that article, I suggested that a possible type mixing may occur when we are not careful enough. Today we will see an example of this.

The mixing can occur if someone mistakenly creates a subclass of Vehicle in the following way –

/**
 * Definition of Vehicle
 */
public abstract class Vehicle<E extends Vehicle<E>> implements Comparable<E> {
    // other methods and properties

    public int compareTo(E vehicle) {
        // method implementation
    }
}

/**
 * Definition of Bus
 */
public class Bus extends Vehicle<Bus> {}

/**
 * BiCycle, new subtype of Vehicle
 */
public class BiCycle extends Vehicle<Bus> {}

/**
 * Now this class’s compareTo method will take a Bus type
 * as its argument. As a result, you will not be able to compare
 * a BiCycle with another Bicycle, but with a Bus.
 */
cycle.compareTo(anotherCycle);  // This will generate a compile time error
cycle.compareTo(bus);    // but you will be able to do this without any error

This type of mix up does not occur with Enums because JVM takes care of subclassing and creating instances for enum types, but if we use this style in our code then we have to be careful.

Let’s talk about another interesting application of recursive bounds. Consider the following class –

public class MyClass {
  private String attrib1;
  private String attrib2;
  private String attrib3;
  private String attrib4;
  private String attrib5;

  public MyClass() {}

  public String getAttrib1() {
    return attrib1;
  }

  public void setAttrib1(String attrib1) {
    this.attrib1 = attrib1;
  }

  public String getAttrib2() {
    return attrib2;
  }

  public void setAttrib2(String attrib2) {
    this.attrib2 = attrib2;
  }

  public String getAttrib3() {
    return attrib3;
  }

  public void setAttrib3(String attrib3) {
    this.attrib3 = attrib3;
  }

  public String getAttrib4() {
    return attrib4;
  }

  public void setAttrib4(String attrib4) {
    this.attrib4 = attrib4;
  }

  public String getAttrib5() {
    return attrib5;
  }

  public void setAttrib5(String attrib5) {
    this.attrib5 = attrib5;
  }
}

If we want to create an instance of this class, then we can do this –

MyClass mc = new MyClass();
mc.setAttrib1("Attribute 1");
mc.setAttrib2("Attribute 2");

The above code creates an instance of the class and initializes the properties. If we could use Method Chaining here, then we could have written –

MyClass mc = new MyClass().setAttrib1("Attribute 1")
    .setAttrib2("Attribute 2");

which obviously looks much better than the first version. However, to enable this type of method chaining, we need to modify MyClass in the following way –

public class MyClass {
  private String attrib1;
  private String attrib2;
  private String attrib3;
  private String attrib4;
  private String attrib5;

  public MyClass() {}

  public String getAttrib1() {
    return attrib1;
  }

  public MyClass setAttrib1(String attrib1) {
    this.attrib1 = attrib1;
    return this;
  }

  public String getAttrib2() {
    return attrib2;
  }

  public MyClass setAttrib2(String attrib2) {
    this.attrib2 = attrib2;
    return this;
  }

  public String getAttrib3() {
    return attrib3;
  }

  public MyClass setAttrib3(String attrib3) {
    this.attrib3 = attrib3;
    return this;
  }

  public String getAttrib4() {
    return attrib4;
  }

  public MyClass setAttrib4(String attrib4) {
    this.attrib4 = attrib4;
    return this;
  }

  public String getAttrib5() {
    return attrib5;
  }

  public MyClass setAttrib5(String attrib5) {
    this.attrib5 = attrib5;
    return this;
  }
}

and then we will be able to use method chaining for instances of this class. However, if we want to use method chaining where inheritance is involved, things kind of get messy –

public abstract class Parent {
  private String attrib1;
  private String attrib2;
  private String attrib3;
  private String attrib4;
  private String attrib5;

  public Parent() {}

  public String getAttrib1() {
    return attrib1;
  }

  public Parent setAttrib1(String attrib1) {
    this.attrib1 = attrib1;
    return this;
  }

  public String getAttrib2() {
    return attrib2;
  }

  public Parent setAttrib2(String attrib2) {
    this.attrib2 = attrib2;
    return this;
  }

  public String getAttrib3() {
    return attrib3;
  }

  public Parent setAttrib3(String attrib3) {
    this.attrib3 = attrib3;
    return this;
  }

  public String getAttrib4() {
    return attrib4;
  }

  public Parent setAttrib4(String attrib4) {
    this.attrib4 = attrib4;
    return this;
  }

  public String getAttrib5() {
    return attrib5;
  }

  public Parent setAttrib5(String attrib5) {
    this.attrib5 = attrib5;
    return this;
  }
}

public class Child extends Parent {
  private String attrib6;
  private String attrib7;

  public Child() {}

  public String getAttrib6() {
    return attrib6;
  }

  public Child setAttrib6(String attrib6) {
    this.attrib6 = attrib6;
    return this;
  }

  public String getAttrib7() {
    return attrib7;
  }

  public Child setAttrib7(String attrib7) {
    this.attrib7 = attrib7;
    return this;
  }
}

/**
 * Now try using method chaining for instances of Child
 * in the following way, you will get compile time errors.
 */
Child c = new Child().setAttrib1("Attribute 1").setAttrib6("Attribute 6");

The reason for this is that even though Child inherits all the setters from its parent, the return type of all those setter methods are of type Parent, not Child. So the first setter will return reference of type Parent, calling setAttrib6 on which will result in compilation error,  because it does not have any such method.

We can resolve this problem by introducing a generic type parameter on Parent and defining a recursive bound on it. All of its children will pass themselves as type argument when they extend from it, ensuring that the setter methods will return references of its type –

public abstract class Parent<T extends Parent<T>> {
  private String attrib1;
  private String attrib2;
  private String attrib3;
  private String attrib4;
  private String attrib5;

  public Parent() {
  }

  public String getAttrib1() {
    return attrib1;
  }

  @SuppressWarnings("unchecked")
  public T setAttrib1(String attrib1) {
    this.attrib1 = attrib1;
    return (T) this;
  }

  public String getAttrib2() {
    return attrib2;
  }

  @SuppressWarnings("unchecked")
  public T setAttrib2(String attrib2) {
    this.attrib2 = attrib2;
    return (T) this;
  }

  public String getAttrib3() {
    return attrib3;
  }

  @SuppressWarnings("unchecked")
  public T setAttrib3(String attrib3) {
    this.attrib3 = attrib3;
    return (T) this;
  }

  public String getAttrib4() {
    return attrib4;
  }

  @SuppressWarnings("unchecked")
  public T setAttrib4(String attrib4) {
    this.attrib4 = attrib4;
    return (T) this;
  }

  public String getAttrib5() {
    return attrib5;
  }

  @SuppressWarnings("unchecked")
  public T setAttrib5(String attrib5) {
    this.attrib5 = attrib5;
    return (T) this;
  }
}

public class Child extends Parent<Child> {
  private String attrib6;
  private String attrib7;

  public String getAttrib6() {
    return attrib6;
  }

  public Child setAttrib6(String attrib6) {
    this.attrib6 = attrib6;
    return this;
  }

  public String getAttrib7() {
    return attrib7;
  }

  public Child setAttrib7(String attrib7) {
    this.attrib7 = attrib7;
    return this;
  }
}

Notice that we have to explicitly cast this to type T  because compiler does not know whether or not this conversion is possible, even though it is because T by definition is bounded by Parent<T>. Also since we are casting an object reference to T, an unchecked warning will be issued by the compiler. To suppress this we used @SuppressWarnings(“unchecked”) above the setters.

With the above modifications, it’s perfectly valid to do this –

Child c = new Child().setAttrib1("Attribute 1")
  .setAttrib6("Attribute 6");

When writing method setters this way, we should be careful as to not to use recursive bounds for any other purposes, like to access children’s states from parent, because that will expose parent to the internal details of its subclasses and will eventually break the encapsulation.

With this post I finish the basic introduction to Generics. There are so many things that I did not discuss in this series, because I believe they are beyond the introductory level.

Until next time.

This is a continuation of an introductory discussion on generics, previous parts of which can be found here.

In this post I will focus on type parameter bounds and their usage.

Bounded Type Parameters

When a generic type is compiled, all occurrences of a type parameter are removed by the compiler and replaced by a concrete type. The compiler also generates appropriate casting needed for type safety by itself during this procedure. This concrete type is typically Object, but compiler can use other types as well. This process is called Type Erasure and will be explained in a future post. For the time being, all we need to understand is that the type information of generic types are lost once they are compiled. For this reason, if we want to access a method/property using a type parameter, we’ll typically be able to access those ones that are defined in the class Object (I am oversimplifying here as we’ll be able to access other methods/properties as well if we use a bound, which we will discuss here in this post). For example, take a look at the following code snippet –

public class MyGenericClass<E> {
    private E prop;

    public MyGenericClass(E prop) {
        this.prop = prop;
    }

    public E getProp() {
        return this.prop;
    }

    public void printProp() {

        //OK, because toString is defined within Object
        System.out.println(this.prop.toString());
    }

    public int getValue() {
        /**
         * NOT OK, because Object doesn’t have
         * compareTo method. Compile-time Error.
         */
        return this.prop.intValue();
    }
}

After compiling the above class, I get the following message –

MyGenericClass.java:37: error: cannot find symbol

return this.prop.intValue();

^

symbol:   method intValue(E)

location: variable prop of type E

where E is a type-variable:

E extends Object declared in class MyGenericClass

1 error

Although the message seems cryptic, the reason behind this is the one that I’ve stated above – when this type is compiled the type parameter E here will be replaced by Object by the compiler, and it doesn’t have intValue method.

So the problem occurs here because the compiler is using Object to replace the type parameters. If I could somehow tell the compiler to use other types during this erasure which has an intValue (Number, for example) method, then this error would have been resolved.

This is exactly what parameter bounds do. By using a type as a bound on a type parameter, I can instruct compiler to use that type during the erasure in place of Object, and then I can easily access the methods/properties defined in that type.

The general syntax for specifying a type parameter bound is as follows –

public class MyGenericClass
    <E extends MyBoundType,
     T extends AnotherBoundType,
     .......>

This also tells the compiler that when a type argument is passed during an instance creation of this generic type, it will be a subtype of MyBoundType, so it can safely let us access the methods that are defined in that type using the type parameter E. If any other type is passed, then the compiler will issue a compile-time error. The extends keyword specify the bound relation between E and MyBoundType. We will use the same keyword even if E is bounded by an interface type, that is, if MyBoundType is an interface. Here extends means both classical extends and implements.

So, if we use Number as our parameter bound for our last example, the error message will be gone because now the compiler will use Number to erase type parameter E, and it has an intValue method defined in it –

public class MyGenericClass<E extends Number> {
    private E prop;

    public MyGenericClass(E prop) {
        this.prop = prop;
    }

    public E getProp() {
        return this.prop;
    }

    public void printProp() {
        // OK, because toString is defined within Object
        System.out.println(this.prop.toString());
    }

    public int getValue() {
        // Now it compiles just fine!
        return this.prop.intValue();
    }
}

This code will now compile just fine.

Remember our generic Insertion Sort algorithm from the first part of the series? We had declared it like this –

public class InsertionSort<E extends Comparable<E>>

This told the compiler that the type arguments that will be passed here will all implement the Comparable interface, so they will have a compareTo method. As a result, compiler allowed us to do this inside the sort method –

for (int i = 1; i <= elements.length - 1; i++) {
    E valueToInsert = elements[i];
    int holePos = i;

    /**
     * See how we are calling compareTo method
     * on the type parameter?
     */
    while (holePos > 0 &&
            valueToInsert.compareTo(elements[holePos - 1]) < 0) {
        elements[holePos] = elements[holePos - 1];
        holePos--;
    }

    elements[holePos] = valueToInsert;
}

This example also shows that we can pass another generic type as a type parameter bound. In fact we can use all Classes, Interfaces and Enums and even another type parameter as a bound. Only primitive and array types are not allowed as a bound.

Multiple and Recursive Bounds

We can define multiple bounds on a single parameter. In this case we use the & operator to separate them from one another –

public class MyGenericClass<E extends MyBoundClass & MyBoundInterface>

This tells the compiler that the type argument that is passed will be a subclass of MyBoundClass and implement MyBoundInterface. So, we will be able to access all the methods/properties defined in those types.

The Java Language Specification requires us to list the class bound first, otherwise the compiler will throw an error. For example, the following will throw an error –

/**
 * Will throw an error because we are not
 * listing the class bound first.
 */
public class MyGenericClass
    <E extends MyBoundInterface
     & MyBoundClass>

We can also declare recursive bounds, so that a bound can depend on itself too. Consider again our stack example from first part of the series. We declared it like this –

public class InsertionSort<E extends Comparable<E>>

Here, the bound is recursive because E itself depends upon E (the one that is supplied to Comparator). If we pass Integer as a type argument when creating an instance of InsertionSort, then the type argument to Comparable will be Integer too.

We can also declare mutually recursive bounds like this –

public class MyGenericClass
    <T extends FirstType<T, U>,
     U extends SecondType<T, U>>
Java Enum Declaration

Let us now consider an example from the Java API itself. We all know that enumerations in Java are objects of some class, and that class extends the Enum class. The declaration of that class looks like this –

public abstract class Enum<E extends Enum<E>>
    implements Comparable<E>, Serializable

Beginners in Java Generics find the first line very confusing. Before explaining the reasoning behind this weird declaration, let us explore an example.

Suppose that we are going to build a software system which will have various types of vehicles (a vehicle simulation system, perhaps?). The vehicles will have a name and a size. We also want to compare vehicles with each other based on their size. An approach for building the vehicle classes might look like this –

public abstract class Vehicle {
    private String name;
    private double length;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }
}

public class Car extends Vehicle implements Comparable<Car> {
    public int compareTo(Car anotherCar) {
        double thisLength = this.getLength();
        double thatLength = anotherCar.getLength();

        if (thisLength > thatLength)
            return 1;
        else if (thisLength < thatLength)
            return -1;

        return 0;
    }

    // other methods and properties
}

public class Bus extends Vehicle implements Comparable<Bus> {
    public int compareTo(Bus anotherBus) {
        double thisLength = this.getLength();
        double thatLength = anotherBus.getLength();

        if (thisLength > thatLength)
            return 1;
        else if (thisLength < thatLength)
            return -1;

        return 0;
    }

    // other methods and properties
}

The problem of the above implementation is pretty obvious – even though the compare method implementations are almost the same among all the subtypes of Vehicle, we still have to maintain different copies of this method. This creates a maintenance problem as now changing the comparison logic forces us to change the code in many places.

To remedy this, we can remove the comparison from the subtypes and move it up in the Vehicle. To do this, we will rewrite those classes as follows –

public abstract class Vehicle implements Comparable<Vehicle> {
    private String name;
    private double length;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public int compareTo(Vehicle anotherVehicle) {
        double thisLength = this.getLength();
        double thatLength = anotherVehicle.getLength();

        if (thisLength > thatLength)
            return 1;
        else if (thisLength < thatLength)
            return -1;

        return 0;
    }
}

public class Car extends Vehicle {
    // car-specific methods and properties
}

public class Bus extends Vehicle {
    // bus-specific methods and properties
}

This approach also has a problem. The above implementation will allow us to compare a car with a bus without any errors –

Car car = new Car();
car.setName("Toyota");
car.setLength(2);

Bus bus = new Bus();
bus.setName("Volvo");
bus.setLength(4);

car.compareTo(bus);    // No error

This is certainly a problem, since comparing a bus with a car should not be done using the same logic that is used to compare a car with a car.

How can we solve this? How can we reuse the comparison logic among all the subtypes, while at the same time raising error flags at compile time whenever someone tries to compare two incompatible types?

In the last example the problem occurred because the compareTo method has a parameter which is of type Vehicle. As a result we were able to pass any subtypes of Vehicle to it, like the way we passed a bus to compare with a car. Let’s try to change the type of this parameter so that now this kind of mixing generates an error. If we want to allow the comparison of a car only with a car, then the argument to the compareTo method must be of type Car. If we change it to Car, we will also need to change the type argument that we are passing to Comparable in the Vehicle class declaration –

public abstract class Vehicle implements Comparable<Car> {
    // other methods and properties

    public int compareTo(Car car) {
        // method implementation
    }
}

But then this will not allow us to compare any other types. We will not be able to compare a bus with another bus. To allow this, we will need to change the parameter to be of type Bus. If we declare a new subtype named Cycle, we will also need this method to support this type too! So we can see that the parameter type of this compare method should vary if we need to enforce compatible comparison.

From the above discussion it’s clear that we need to parameterize the parameter type of the compareTo method, and in turn, parameterize the Vehicle class itself. If we do this, we will then be able to pass Car, Bus, and Cycle etc. as its type argument, which in turn will be used as the parameter type of the compare method. In general, after we declare Vehicle as a generic type, all of its subtypes will pass themselves as a type argument while extending from it, so that the parameter type of this compareTo method matches their type –

public abstract class Vehicle<E> implements Comparable<E> {
    // other methods and properties

    public int compareTo(E vehicle) {
        // method implementation
    }
}

/**
* Now this class’s compareTo version will take a Car type
* as its argument.
*/
public class Car extends Vehicle<Car> {}

/**
* Now this class’s compareTo version will take a Bus type
* as its argument.
*/
public class Bus extends Vehicle<Bus> {}

/**
* Doing something like this will now generate a
* compile-time error.
*/
car.compareTo(bus);

This approach solves our last problem that we were facing, but introduces a new one. After converting Vehicle to a generic type and using the type parameter as the parameter type of the compare method, it looks like this –

public int compareTo(E anotherVehicle) {
    double thisLength = this.getLength();

    // Now the following line is an error.
    double thatLength = anotherVehicle.getLength();

    if (thisLength > thatLength)
        return 1;
    else if (thisLength < thatLength)
        return -1;

    return 0;
}

Since we didn’t put any bound on the type parameter, and Object class doesn’t have a getLength method, compiler will generate an error. We get to call this method on a variable of type E only if it’s bounded by Vehicle itself, because then compiler will know that variables of this type will have this method. So our compare method will work only if E is bounded by Vehicle itself! After this modification, the classes look like below –

public abstract class Vehicle<E extends Vehicle<E>>
        implements Comparable<E> {

    private String name;
    private double length;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public int compareTo(E anotherVehicle) {
        double thisLength = this.getLength();
        double thatLength = anotherVehicle.getLength();

        if (thisLength > thatLength)
            return 1;
        else if (thisLength < thatLength)
            return -1;

        return 0;
    }
}

public class Car extends Vehicle<Car> {
    // Car-specific properties and methods
}

public class Bus extends Vehicle<Bus> {
    // Bus-specific properties and methods
}

// and in main
Car car = new Car();
car.setName("Toyota");
car.setLength(2);

Bus bus = new Bus();
bus.setName("Volvo");
bus.setLength(4);

car.compareTo(car);       // Works as expected
car.compareTo(bus);       // compile-time error

Even with the above example, a certain kind of type mixing is possible. Rather than discussing it here, I am going to leave it to you to figure it out. If you can’t, check out the next post of this series!

I guess now you know why the Enum class is declared in that way. This kind of recursive bound allows us to write methods in a supertype which will take its subtypes as its arguments, or returns them as return value. I encourage you to check out the source code of the Enum class to find out these methods.

That’s it for today. Stay tuned for the next post!

Resources

  1. Java Generics and Collections
  2. Java Generics FAQs by Angelika Langer

This is a continuation of an introductory discussion on generics, previous parts of which can be found here.

Before jumping into subtyping in generics, I thought it will be good if I talk a little about generic methods and automatic type inference.

Generic Methods

Just like generic class, we can define generic methods in Java.  A generic method is a method which defines its own type parameters. In this case, the type parameter’s scope is limited to the method where it’s declared. To declare a generic method, we just list the type parameters before its return type, like this –

public class MyClass {
    public static <T> void myFirstGenericMethod(T param) {
        System.out.println(param);
    }
}

We can invoke this generic method in the following way –

MyClass. <String>myFirstGenericMethod("Hello World");

If this was an instance method, then we would have called it like this –

myInstance. <String>myFirstGenericMethod("Hello World");

Notice how we have passed the type argument while calling the method. Generally, the rule is as follows –

class/instance_var. <type_argument_list>methodName(argument list…..);

Our above method call will also compile without specifying the type parameters explicitly. This happens because of type inference – the java compiler’s ability to automatically determine the type argument during generic method call/generic instance creation. We will talk more about this in a few moments.

Let’s write another useful generic method which will add all elements of an array into a list –

public class Utils {
    public static <T> void addAll(List<T> myList, T[] arr) {
        for (T elem: arr) {
            myList.add(elem);
        }
    }
}

The above code should be self-explanatory at this point.

Type Inference

Type inference is Java compiler’s ability to look at generic method invocation and instance creation to determine the type arguments that make the code work. This algorithm is capable of determining the type of the arguments and the type that the result is being assigned or returned, provided that there is enough information for the inference algorithm to do so.

According to the official Oracle Java tutorial

The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.

There are two situations where type inference algorithm comes into play –

  1. When an object of a generic type is being created
  2. When a generic method is being invoked
Type Inference during generic instance creation

Generally, type inference for instance creation works like this – first, the compiler tries to deduce the type arguments from the constructor arguments in the object creation expression (the one with the new). If it fails to deduce the type arguments for any of the type parameters from there, it then uses information from the context in which the creation expression appears.

In one of my previous posts, I have demonstrated a short-cut way to create generic instances without specifying the type argument –

MyPrettySimpleGenericClass<Integer> item = new
        MyPrettySimpleGenericClass<>();

Here, we see that the instance that is being created is being assigned to a variable, which is of type MyPrettySimpleGenericClass<Integer>. This line will be valid only if the generic instance being created also has the Integer as its type argument (no, any subtype/supertype of Integer will also not do, we’ll see why in a future post). When type inference algorithm tries to deduce the type argument that will be applicable for this instance creation expression, it first takes a look at the constructor arguments. Since the above code doesn’t have any, it then takes a look at the left hand side of the assignment operator and sees that only Integer can make the statement valid. Thus it automatically passes Integer as the type argument to the generic instance being created.

If constructor arguments are available and if the inference algorithm can determine the applicable type arguments from them, then it completely ignores the assignment context. Let’s consider an example –

List<Number> list = new ArrayList<>(Arrays.asList(0L, 0L));

We are passing long values to the asList method, which takes an arbitrary number of arguments as its input, and returns an object of type List containing those elements. As a result, the inference algorithm determines its return type to be List<Long>, and returns an instance of this type. This returned value is then again used by the inference algorithm to determine the type argument of the ArrayList being created, which is finally set to Long as well. Since List<Long> and List<Number> are totally incompatible type (again, more on this in a future post), the compiler generates an error (although in Java 8 it compiles fine).

What happens if there are no constructor arguments, or assignment of the generic instance being created? Let’s consider an example of that too –

Iterator<String> it = new ArrayList<>().iterator();

In the above example, the object creation expression occurs inside a chain of method calls. As the type inference for object creation expression is only allowed for an assignment context (this is only true for JDK 7 as JDK 8 has improved the inference algorithm a bit by including the method invocation context), the compiler is unable to determine the correct type. As a result, a compile-time error is issued by the compiler.

Similar reasoning can be applied for the following blocks of code –

class TestDrive {
    static void printAll(List<Integer> list) {
        for (Integer i: list) {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        printAll(new ArrayList<>());  // Error in Java 7
    }
}

In these cases, the recommended approach is to introduce a variable and assign the object instance to it first. It is then used in the expression replacing the object creation expression.

Type inference generally fails for anonymous inner classes. Consider another example –

Comparator<Integer> cmp = new Comparator<>() {

    @Override
    public int compare(Integer o1, Integer o2) {
        return o1.compareTo(o2);
    }
};

In the above example, the type inference cannot determine the applicable type arguments from the context, and will throw a compilation error.

Type Inference during generic method invocation

Type inference algorithm for generic methods works in the same way as the instance creation. Here, type inference first observes the method arguments to determine the type parameter, and then observes the context in which it is being used.

If we recall our myFirstGenericMethod method, we can see that the type inference is capable of determining the appropriate type argument by observing the string argument. Same thing is true for our addAll utility method.

What happens if the method doesn’t have any arguments which correspond to its type parameter? In this case the compiler tries to determine the type from the method invocation context. Let’s write a method which will create lists for us if we specify the initial capacity –

static <T> List<T> createList(int capacity) {
    List<T> list = new ArrayList<>(capacity);
    return list;
}

We can call it in the following way –

List<Integer> list = createList(10);

Our utility method doesn’t have any arguments which correspond to the type parameter. Hence inference algorithm cannot deduce anything by observing the arguments in the method invocation. It then tries to observe the calling context and sees that the result returned by the method is being assigned to a reference of type List<Integer>, and determines the type argument to the method to be Integer.

What if the above method is not being called from an assignment context? The compiler cannot determine the type argument! If we call our previous printAll method like this –

printAll(createList(10));

then the compiler will throw an error (JDK 8 can determine the type argument). We have to specify the type argument explicitly in this case, or introduce a variable to hold the value returned by the first method, and then pass it as argument to the latter.

We can declare generic methods in a generic class declaration too. What happens if the type parameter of the generic method matches with the type parameter of the generic class? I leave this to the reader to experiment!

Lastly, the Java Specification says that we can only specify type arguments when we call generic methods using dot notation. As a result, calling our createList method like this will result in a compile-time error (obviously from inside the class where it’s defined) –

<Integer>createList(5);  // Error, won’t compile

In this case, if the generic method is a static one, we use class name to invoke the method. If it’s an instance method, we use an instance reference (or this / super) to call it.

That’s it for today. Stay tuned for the next post!

Resources
  1. Java Generics and Collections by Naftalin, Philip Wadler
  2. Angelika Langer: Java Generics Faqs

This is a continuation of my introductory tutorial on Generics. Previous posts in this series can be found here.

Why should we use Generics

I intended to write about this after I’ve demonstrated some generics examples so that their usefulness become apparent to the readers. So let’s see what the official tutorial of Java has to say about the usefulness of generics, or, why should we use them –

  1. Stronger type checks at compile time
  2. Elimination of casts
  3. Enabling programmers to implement generic algorithms

The first two are very closely related. We have already seen how generics allow us to write generic algorithms. It’s time to focus on the first two.

Point number one – stronger type checks at compile time

Generics were specifically introduced to work with the Java Collections API. Before generics era, Lists and ArrayLists didn’t use generics, and were used like this –

/* Create a list to hold some
 * string values.
 */
List myList = new ArrayList();

myList.add("Hello ");
myList.add("World ");
myList.add("from Java");
myList.add(1);    // Oh no...

Iterator it = myList.iterator();
while(it.hasNext()) {
  String s = (String ) it.next();
  System.out.print(s);
}

If you are new to Collections, don’t worry, they are not that hard to learn. For the time being, you can simply consider myList to be something like an array, or a collection, where we can add elements using the add method, and later traverse them using a standard iterator.

This is how we used collections in the pre-generic era. To be used as a collection for any types, the add method expects an Object as its argument and casts/boxes any other types to it. As you can see from the above code, one can easily put integers into a collection of strings if they are not careful enough, just like we did in line number 9. In this case the program will compile without any trouble, but we will get a ClassCastException at runtime at line number 13, because we cannot cast an integer into a string.

Some people might consider my example far-fetched, saying that the scenario described above is less likely to occur in real world. I would like to tell them that the above scenario is a very simplified one. For example, you might call a library method in your program which returns a collection of strings, and you didn’t know it in advance and put integers in that list, resulting in runtime exception. If this is also not convincing, consider the Date class in Java which is defined in two different packages – java.util and java.sql, and mixing them together in the same collection will likely result in a runtime exception. It was programmer’s responsibility to make sure that a collection didn’t contain elements from various types, and programmers did make those mistakes.

When we use generics, the above problem doesn’t occur. Now it’s the compiler’s responsibility to make sure that a collection doesn’t get polluted by containing elements from more than one type. When we try to put an integer into a collection of strings, compiler will generate an error at compile time, rather than at runtime –

/* Create a list to hold some
 * string values.
 */
List<String> myList = new ArrayList<String>();

myList.add("Hello ");
myList.add("World ");
myList.add("from Java");
myList.add(1);    // Now this is a compile time error

Iterator<String> it = myList.iterator();
while(it.hasNext()) {
  String s = it.next();
  System.out.print(s);
}

Using generics in this way ensures that our list will contain only elements of a certain type, and we will not run into any runtime exception. From the java best practice guidelines, we know that catching and fixing errors at compile time is much easier than catching them at runtime (more on this in a future article).

Point number two – elimination of casts

If you check out the second example, you’ll see that the cast at line number 13 is no longer required. This is because when we used generics, we have explicitly told the compiler that this collection will only contain a collection of strings. We will add only strings to it, and we will retrieve only string values from it. If you could check the method signature of the next method now (just like I did using Eclipse by hovering the cursor over this method), you’ll see that it too returns a string value where in the first example it returned an object of type Object. Eliminating cast this way also helps us to reduce the possibility of encountering any runtime exception (although implicitly this is a consequence of the first point).

Point number three – enabling programmers to implement generic algorithms

I have already explained this point in the previous two articles. If like to visit them again, here is the first one and here is the second one :-).

With the above three usefulness, I’d like to mention another one which I have described below.

Point number four – enabling programmers to write clear and concise code

Let’s write a simple program – put five numbers into a list and add them together. Here’s how we did it before generics were introduced –

List intList = Arrays.asList(new Integer[] {
    new Integer(1), new Integer(2), new Integer(3),
    new Integer(4), new Integer(5)
});
int sum = 0;

Iterator it = intList.iterator();
while(it.hasNext()) {
    sum += ((Integer) it.next()).intValue();
}

System.out.println("The sum is: " + sum);

Reading this code is not too easy. It’s also not expressive, as we cannot tell what types of elements we intend to store in our list.

If we write the same code using generics, then it becomes something like this –

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5); // We can do this
                                                      // because of Autoboxing
int sum = 0;

for (int i: intList) {
    sum += i;
}

System.out.println("The sum is: " + sum);

You can probably read this code without much explanation. It’s clear and much shorter from it’s non-generic counterpart. Here we have made use of couple of other Java language features – the for-each loop and autoboxing/unboxing. Indeed generics work well with these features.

I hope you are now convinced about generics :-).

That’s it for today. Hope to write another post real soon. Stay tuned!

Additional Resources

This is a continuation of an introductory Generics tutorial, previous part of which can be found here.

Generics Instantiation Syntax

In the previous post we have learned how to declare a generic class. We have also learned its formal definition. Now it’s time to learn how to create instances of the generic class, formally.

To create an instance of a generic type, we do generic type invocation, which replaces the type parameter with a concrete type. We have seen multiple examples of this in the previous article. Remember our MyPrettySimpleGenericClass from the previous post? If you don’t, here is the definition –

public class MyPrettySimpleGenericClass<E> {

    private E item;

    public void setItem(E item) {
        this.item = item;
    }

    public E getItem() {
        return item;
    }

    public void printItem() {
        System.out.println(item.toString());
    }

Then, to create an instance of this class, we do the following –

MyPrettySimpleGenericClass<Integer> item = new
    MyPrettySimpleGenericClass<Integer>;

In the above code, we have performed a generic type invocation by replacing the type parameter with a concrete type Integer, which makes this object to work with all the integer values. We call Integer a type argument in this case. An invocation of a generic type in this way creates what we call a parameterized type. Our parameterized type in this case is MyPrettySimpleGenericClass<Integer>.

You can pass any non-primitive type as a type argument. You can even pass another parameterized type too, because they are also non-primitive. Consider the following example –

MyPrettySimpleGenericClass<List<Integer>> item = new
    MyPrettySimpleGenericClass<List<Integer>>();

In the above example, the type parameter is another parameterized type, which was obtained by parameterizing the List<E> generic interface (it’s part of the standard Java API, specifically the Collection API and I intend to write something about them too!).

You can see that this generic method invocation thingy looks somewhat similar to method invocation, except that during a method invocation you pass values as arguments (yes, Java is pass-by-value, and if you are wondering about it, please have patience as I intend to write a post about it in future), and here you pass types as arguments.

Now, some of you might be wondering about the constructor syntax of a generic type, after seeing the <Integer> part right before the parentheses in the above code. Do we also have to put type parameters in the constructor of a generic type?

Short answer – No. You declare a constructor of a generic type like any other constructor. You don’t need to put a type parameter right before the constructor parentheses (in fact you’ll get a compilation error if you try something like that) – putting it right after the class name is enough, unless your constructor itself is a Generic Method (I promise I won’t run away until I write a post about it) which introduces a new type parameter!

In JDK 7 and later, you can omit the type argument during the invocation of the constructor of the generic type, provided that the compiler can determine, or infer (yes, Type Inference will be coming up in a future post), the type argument from the context. Taking advantage of this feature, we can modify our previous object instantiation in the following way –

MyPrettySimpleGenericClass<Integer> item = new
    MyPrettySimpleGenericClass<>();

This pair of angle brackets, right before the parentheses, is conventionally known as the diamond. It’s of great convenience when writing generics  as you have to type less.

Enough theoretical stuff. Let’s put all these things together and write something useful, because the best way to learn something is by actually doing it.

A Useful Example – Implementing a Generic Stack

In this example, we will build a Stack. This stack will be generic – we will use it for different types of items based on different type arguments.

Let’s see the declaration of our Stack class –

import java.util.NoSuchElementException;

public class Stack<E> {
    private long size;
    private long count;
    private StackElement top;

    private class StackElement {
        private E element;
        private StackElement next;
    }

    public Stack() {
        this(Long.MAX_VALUE);
    }

    public Stack(long size) {
        this.size = size;
        this.count = 0;
    }

    public long getSize() {
        return size;
    }

    public long getCount() {
        return count;
    }

    public boolean isEmpty() {
        return count == 0;
    }

    public boolean isFull() {
        return getCount() == size;
    }

    public void push(E element) throws UnsupportedOperationException {
        if (isFull()) {
            throw new UnsupportedOperationException("Push operation is " +
                "not supported on full stack");
        }

        StackElement elem = new StackElement();
        elem.element = element;
        elem.next = top;
        top = elem;
        count++;
    }

    public E pop() throws NoSuchElementException{
        if (isEmpty()) {
            throw new NoSuchElementException("Stack is empty");
        }

        StackElement topElement = top;
        top = top.next;
        count--;

        return topElement.element;
    }

    public E peek() throws NoSuchElementException {
        if (isEmpty()) {
            throw new NoSuchElementException("Stack is empty");
        }

        return top.element;
    }
}

Some points about the above stack implementation –

  1. We generally use arrays to store stack elements. This approach won’t work here, because we cannot create an array of generic types. Instead, we will be using the Linked List implementation.
  2. We have created an inner class to represent a linked list element. This is a perfect example of when an inner class should be used. We wanted to make a type which will store an element of type E, and will also hold a reference to the next element. If we make it a top-level class, we won’t be able to access the type parameter E from it. So, we needed a type which will have access to internal information of another type. As a result, we use an inner class (yes, more on inner classes will come next, in the near future, perhaps within the next ten years…..hmmmmmm……..).
  3. Notice that we have declared our inner class as private. If we don’t declare it as such, then it may also be accessed from outside Stack, thus leaking our implementation detail in the outside world.
  4. Notice the declaration of pushpop and peek method. The first one throws an UnsupportedOperationException if an element is pushed while the stack is full, and the last two throws a NoSuchElementException when these operations are done in an empty stack. Some might think of using other exception classes, or building their own with more customization. As for this example, it’s a simple one, so I will be using these two.

Ok, now let’s see a simple test drive –

public class Main {
    public static void main(String[] args) {
        Stack<Integer> intStack = new Stack<>();
        intStack.push(10);
        intStack.push(20);
        intStack.push(30);
        while(!intStack.isEmpty()) {
            System.out.println(intStack.pop());
        }

        Stack<Double> doubleStack = new Stack<>();
        doubleStack.push(10.5);
        doubleStack.push(20.34);
        doubleStack.push(30.56);
        while(!doubleStack.isEmpty()) {
            System.out.println(doubleStack.pop());
        }

        Stack<String> stringStack = new Stack<>();
        stringStack.push("Hello");
        stringStack.push("to");
        stringStack.push("Generics!");
        while(!stringStack.isEmpty()) {
            System.out.println(stringStack.pop());
        }
    }
}

See how we are using our stack for different types? Aren’t generics awesome 😀 ?

Play with it as long as you want. Tweak the example in as many ways as you like. Try creating an Integer stack and pushing a string into it. Do it the other way round. See what errors/exceptions you get. Also, try to implement other data structures, like Queue, with generics. See how awesome they become!

I have put this implementation in my github repository along with couple of simple test cases (yes, if it was a production quality code, there would have been more and more test cases), in case anyone wants to play with it.

And this is where I’d like to finish the second part. Hope to see you soon!