An example of method level generic type usage

This example shows how to use generic type in a design pattern.
The following code will structure a process to separate logic code from routine tasks.

First, create an interface and an unimplemented method, which will be called in Executor class:

public interface Executable<T> { T execute(); }

Second, code the routine tasks, and insert the logic to be execute:

public class Executor {
    public <T> T process(Executable<T> e) {
        //pre execution. e.g.: start transaction
        T t = e.execute();
        //post execution. e.g.: commit transaction, close resource etc.
        return t;
    }
}

Finally, call the Executor to process your task, and code the business logic:

public class Caller {
    public static void main(String args[]) {
        DeterminedType t = new Executor().process(() -> {
            //code to deal with the business logic
            return result; //the type of the result returning here will determine the type of t
        });
    }
}
Advertisements

A summary of Generic Type

There are 2 levels of Generic Type: class level & method level.

Class Level:

public class ExampleClass<T>{}

Method Level:

public <T> ReturnType exampleMethod(ParameterType parameter){return null;}

Generic Type works very much like any kind of variables. You need to declare them before using. The above Generic Type place holders <T> are the only places you can declare generic types. It means any “generic types” appear else where are not declarations, but references of <T>.

For example:
public class ExampleClass<T> extends SuperClass<T>{}
The first <T> is declaration, and the second is just a reference. As an effect, you can’t have something like this:

Wrong:

public class ExampleClass<T> extends SuperClass<T extends Type>{}

because if you want to bound a type parameter on a generic type, you have to do it while it’s declared, like this:

Right:

public class ExampleClass<T extends Type> extends SuperClass<T>{}

Another trick with this example is, if <T> of SuperClass is bounded to a type in its own definition, the <T> of ExampleClass must narrow its type to fit the <T> of SuperClass.

Wrong:

public class SuperClass<T extends Type>{}
public class ExampleClass<T> extends SuperClass<T>{}

Right:

public class SuperClass<T extends Type>{}
public class ExampleClass<T extends Type> extends SuperClass<T>{}

For the ExampleClass<T extends Type>, T can also extend from a subclass of Type since subclass has an “is” relationship to its parent class.

super

super is opposite to extends, and is commonly used with consumer pattern.

Wildcard extends:

List<? extends T>

It indicates each element in the list is an instanceof T.

Wildcard super:

List<? super T>

It means the type of each element equals the type of T, or the types of its parents.

*Search PECS (Producer Extends Consumer Super) for details about its usage.