Generic Methods Tutorial

You might be thinking that a generic method is just a method contained inside of a generic class. To a limited extent, that is sort of true. A true generic method will have its own type parameters that are independent of the class type parameters. A generic method does not have to be contained inside of a generic class, a generic method can be in a regular run-of-the-mill class.
The declaration statement for a generic class looks like this:
( <type-variable> ) (return type) (method name) (parameter list) { ... }

<V extends Number> double calculateVolume(V length, V height, V width) {
     return (length.doubleValue() * height.doubleValue() * width.doubleValue());
}
The example above also makes use of bounded type parameters. Please watch my Generics: Bounded Type Parameters Tutorial as this tutorial will expand on several concepts from that tutorial. In this tutorial I will demonstrate the use of generic methods in both a generic class and a regular class.



Open the command prompt (CMD - see the Getting Started ) and type in the following commands.

C:\Windows\System32>cd \
C:\>md Java
C:\>cd Java
C:\Java>
C:\Java>md GenericMethods
C:\Java>cd GenericMethods
C:\Java\GenericMethods>Notepad GenericMethods.java

Copy and Paste, or type the following code into Notepad and be sure to save the file when you are done.


class GenericMethods {
    public static void main(String args[]) {
        Box<Integer> box1 = new Box<Integer>(7, 2, 10); // autoboxing parameters
        Box<Double> box2 = new Box<Double>(11.5, 5.0, 6.5);        
        System.out.println("The volume of box1 is: " + box1.getVolume());
        System.out.println("The volume of box2 is: " + box2.getVolume());

        System.out.println("Invoking static generic method calculateVolume: " + Box.calculateVolume(5, 7, 12)); // autoboxing to Integer
        System.out.println("Invoking static generic method calculateVolume: " + Box.calculateVolume(5.3, 7, 12.1)); // autoboxing to Double
        System.out.println();

        OldBox ob = new OldBox(5, 5, 5);
        System.out.println("The volume of ob is: " + ob.getVolume());
        System.out.println("OldBox calculateVolume: " + OldBox.calculateVolume(6.1, 7, 3.6)); 
        System.out.println("OldBox calculateVolume: " + OldBox.calculateVolume(new Byte((byte)0xA), new Double(4.75), new Integer(5))); 
        System.out.println();

        byte b = 0xA;
        short s = 8;
        int i = 7;
        float f = 3.5f;
        double d = 1.25;

        VolumeDisplayer.cubeVolume(b, i, f, "my cube");
        VolumeDisplayer.cylinderVolume(d, s, "my cylinder");
    }
}

class Box<T extends Number> {
    private T length;
    private T height;
    private T width;

    Box(T length, T height, T width) {
        this.length = length;
        this.height = height;
        this.width = width;
    }

    double getVolume () {
        return (length.doubleValue() * height.doubleValue() * width.doubleValue());
    }

    static <V extends Number> double calculateVolume(V gLength, V gHeight, V gWidth) {
        return (gLength.doubleValue() * gHeight.doubleValue() * gWidth.doubleValue());
    }
}

class OldBox {
    private int length;
    private int height;
    private int width;

    OldBox(int length, int height, int width) {
        this.length = length;
        this.height = height;
        this.width = width;
    }

    int getVolume () {
        return (length * height * width);
    }

    static <T extends Number> double calculateVolume(T gLength, T gHeight, T gWidth) {
        return (gLength.doubleValue() * gHeight.doubleValue() * gWidth.doubleValue());
    }
}

class VolumeDisplayer {

    static <T extends Number> void cubeVolume(T gLength, T gHeight, T gWidth, String s) {
        System.out.println("The volume of " + s + " is: " + (gLength.doubleValue() * gHeight.doubleValue() * gWidth.doubleValue()));
    }

    static <T extends Number> void cylinderVolume(T radius, T height, String s) {
        System.out.println("The volume of " + s + " is: " + (3.14159 * (radius.doubleValue() * radius.doubleValue()) * height.doubleValue()));
    }

}



Now switch back to the command prompt (CMD) and type in javac GenericMethods.java and press Enter.
Now type in java GenericMethods and press Enter.


C:\Java\GenericMethods>javac GenericMethods.java
C:\Java\GenericMethods>java GenericMethods
The volume of box1 is: 140.0
The volume of box2 is: 373.75
Invoking static generic method calculateVolume: 420.0
Invoking static generic method calculateVolume: 448.91

The volume of ob is: 125
OldBox calculateVolume: 153.72
OldBox calculateVolume: 237.5

The volume of my cube is: 245.0
The volume of my cylinder is: 39.269875




Final thoughts

A generic method does not rely on object state and typically has its own type variables that are local to the scope of the generic method.


Tutorials