Q: covariant return or generic I want to have a method in an interface that returns a class whose type is not defined in the package. The implementing class will then return a specific type. I can see at least 3 methods how I can do this, shown below as fn1, fn2 and fn3. In all cases there is some form of unchecked cast. Is any of these methods preferred? or is there something better? (assume that the interface I1 and the method dostuff are in some other jar package and do not have access to the Test or the Integer class)
public class Myclass {

    public interface I1
    {
        Object fn1();
        <T> T fn2();
        <T> T fn3();
    }

    public class Test implements I1
    {

        @Override
        public Integer fn1() {
            return new Integer(1);
        }

        @Override
        public <T> T fn2() {
            return (T) new Integer(2); //requires cast to T
        }

        @Override
        public Integer fn3() { //automatic unchecked conversion to T in return value
            return new Integer(3);
        }       
    }

    public static void main(String[] args) {
        Myclass c = new Myclass();      
        I1 t = c.new Test();
        Integer i = (Integer) t.fn1(); //cast required here since I1.fn1() returns Object
        Integer j = t.fn2();
        Integer k = t.fn3();
        dostuff(t);

    }

    static void dostuff(I1 p)
    {
        Object i = p.fn1();
        Object j = p.fn2();
        Object k = p.fn3();
    }

}


A: Can't you use generics with the Interface? Like
public interface I1<T> {

    T fn1();
    // etc

}

Then there's no casting required when you refer to T.
That's what I prefer, at least. You can then also of course specify what you want T to be using
<T extends myInterface>


A: I would do it this way
public interface I1<T> {
    T fn1();
}

public class Test implements I1<Integer> {
    @Override
    public Integer fn1() {
        return new Integer(1);
    }
}

public static void main(String[] args) {
    Myclass c = new Myclass();
    I1<Integer> t = c.new Test();
    Integer i = t.fn1();  <-- no cast
}

