Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generic method returns different type - no exception

I have found some strange code, where I said "This is never called, because it would throw a class cast Exception". Well the code gets called and its working.

Can anybody explain me: Why is this working?

The method getZipList() is defined to return a List of Strings, but the internal Logic is returning a List with different objects. Also inside the main method a List of Strings is expected as 'list' but the list contains something different.

public class GenericMethodList{
    public static void main(String [] args)
    {
        GenericMethodList o = new GenericMethodList();
        List<String> list = o.getZipList(true);

        Iterator<?> iter = list.iterator();
        while (iter.hasNext()){
            ZipCode zipplace = (ZipCode) iter.next();
            System.out.println(zipplace.value);
        }
    }

    public List<String> getZipList(boolean someParameter){
        //why is this not throwing an exception at runtime?
        List list;
        if(someParameter){
            list = getZipCodes();//List<ZipCode>
        } else {
            list = getZipStreets();//List<ZipStreet>
        }
        return list;
    }

    private List<ZipCode> getZipCodes(){
        List<ZipCode> list = new ArrayList<ZipCode>();
        list.add(new ZipCode("code1"));
        list.add(new ZipCode("code1"));
        return list;
    }

    private List<ZipStreet> getZipStreets(){
        List<ZipStreet> list = new ArrayList<ZipStreet>();
        list.add(new ZipStreet("street1"));
        list.add(new ZipStreet("street2"));
        return list;
    }

    public class ZipCode{
        public String value;
        public ZipCode(String value){
            this.value = value;
        }
    }

    public class ZipStreet {
        public String value;
        public ZipStreet(String value){
            this.value = value;
        }
    }
}

Thank you very much for your explanations.

like image 553
Phil Avatar asked Aug 09 '13 09:08

Phil


Video Answer


1 Answers

You must be getting an "unchecked cast" compiler warning for the return list line because there you are returning a raw type as a parameterized type. At this position an "unchecked cast" is performed from the raw type (for which there is simply no info on the type of elements) into the parameterized type which is declared for the method. The type parameter could be any arbitrary type—the compiler simply has no idea what to allow and what to prevent.

This cast is unchecked in the sense that it cannot be performed at runtime: at runtime the type parameters of the list instance are erased anyway, so the JVM has no idea you are doing a bad thing there.

like image 67
Marko Topolnik Avatar answered Sep 30 '22 13:09

Marko Topolnik