Search code examples
javagenericscastingtype-safety

Casting INSIDE the Generic classes in java


I know that we can skip casting by adding using the Generics in java as follows. (When we are using it outside of the Generic class.)

But if we are doing some logics on the type object (T item) inside the generic class (Container<T>) we should check the instance of and specially cast isn't it? So we can use it to skip casting out side the generic classes.

Please check the commented code in the public void setItem(T item) method.

I want to know whether my understanding is correct or am I missing something

Client.java

    public class Client {

        public static void main(String[] args) {


            // String container
            Container<String>   stringContainer     = new Container<String>();
            stringContainer.setItem("Test");
            //stringContainer.setItem(new StringBuffer("")); // compilation error, type safety checking 

            System.out.println(stringContainer.getItem().toUpperCase()); // No need to cast


            // Integer container
            Container<Integer> integerContainer = new Container<Integer>();
            integerContainer.setItem(123);

            //integerContainer.setItem("123"); // compilation error, type safety checking 

           System.out.println(integerContainer.getItem().intValue()); // No need to cast

        }

    }

Container class

class Container<T> {

    private T item;

    public T getItem(){
        return item;
    }

    public void setItem(T item){

        /* If I' doing some thing on item then I have to check the instance of and cast isn't it?

        if(item instanceof String){
            System.out.println("setItem().((String)item).toUpperCase() : " + ((String) item).toUpperCase());
        }
        */

        this.item = item;
    }
}

Reference : http://nandirx.wordpress.com/category/java-2/generics-java/


Solution

  • Yes, your understanding is correct.

    Adding type specific code here, however, defeats the purpose of generics.

    A better solution would be the following.

    Client.java

    public class Client {
    
        public static void main(String[] args) {
            // String container
            Container<String> stringContainer = new StringContainer();
            stringContainer.setItem("Test");
            //stringContainer.setItem(new StringBuffer("")); // compilation error, type safety checking 
    
            System.out.println(stringContainer.getItem().toUpperCase()); // No need to cast
    
        }
    
    }
    

    Container.java

    class Container<T> {
    
        private T item;
    
        public T getItem(){
            return item;
        }
    
        public void setItem(T item){
    
            this.item = item;
        }
    }
    

    StringContainer.java

    class StringContainer extends Container<String> {
    
        @Override   
        public void setItem(String item){           
            System.out.println( item.toUpperCase() ); 
            super.setItem( item );
        }
    }