Thursday, May 10, 2012

C# said, Java said. OOP for generics

C# said

using System.Collections.Generics;

class Program {

    public static void Main (string[] args) {
    
        IList<Animal> animals = new List<Animal>();
        AddAnimal(animals);
        foreach (Animal animal in animals) {
            Console.WriteLine (animal);
        }
    
        IList<Dog> dogs = new List<Dog>();
        AddAnimal(dogs);
        foreach (Animal animal in dogs) {
            Console.WriteLine (animal);
        }
        
    }
    
    public static void AddAnimal<T>(IList<T> animals) where T : Animal, new() {
                
        foreach(Animal a in animals) {
        }
                
        T x = new T();
        animals.Add(x);
    }   

}


class Animal {
}

class Dog : Animal {
}

class Plant {
}

Java said

import java.util.*;

public class Program {
    public static void main(String[] args) 
        throws InstantiationException, IllegalAccessException 
    {

        List<Animal> animals = new ArrayList<Animal>();
        addAnimal(animals, Animal.class);
        for (Animal animal : animals) {
            System.out.println (animal);
        }
    
        List<Dog> dogs = new ArrayList<Dog>();
        addAnimal(dogs, Dog.class);
        for (Animal animal : dogs) {
            System.out.println (animal);
        }

    }
    
    
    public static <T extends Animal> void addAnimal(
        List<T> animals, Class<T> clz)
        throws InstantiationException, IllegalAccessException
    {

        for(Animal a : animals) {
        }

        T x = clz.newInstance();
        animals.add(x);
        
    }
        
}

class Animal {
}

class Dog extends Animal {
}

class Plant {
}

The notable difference is between their instantiation of the generic's type. Whereas in C# you just say new T(), the same thing can't be done as straightforward as it be in Java. As Java generics employs type erasure, you need to explicitly pass to the function the type you want to instantiate.


The extends on our sample Java generics code is called upperbound wildcard, mostly used for getting values

The super on generics is called lowerbound wildcard, mostly used for putting values.


Though in our example, we use extends for both getting value and putting value. In order to put the value, we pass(a necessity on Java,Java erases the type of generic's parameter T) the class' type to the function.




To read something about get-put principle: http://www.ibm.com/developerworks/java/library/j-jtp07018/index.html


Another approach for using the generic on method parameter(e.g. good for collection) is to use lowerbounded generic parameters, read it at: http://www.anicehumble.com/2012/05/lowerbound-generics-in-java.html

No comments:

Post a Comment