Vejto
Vejto

Reputation: 1314

Unable to infer generic type when also used as type param in another generic class

Consider the code below. Why do I have to cast to String in the withCastTest and not in the withoutCastTest?

It seems like java is unable to infer the generic class when the type parameter is used as a type parameter in another generic class. In the withoutCastTest I send the type parameter as a normal parameter and it can infer the correct type. Why is that? Anyway around it?

Sry if the question is formulated weird, I'm not sure about the naming conventions.

public class RandomHelper {

    public interface RandomInterface<E> {
        public abstract E get();
    }

    public static abstract class Randomable<E> implements RandomInterface {

        protected E object;

        public Randomable(E object) {
            this.object = object;
        }

    }

    public static <E> E withCastTest(RandomInterface<E> action) {
        E savedObject = action.get();
        return savedObject;
    }

    public static <E> E withoutCastTest(RandomInterface<E> action, E e) {
        E savedObject = action.get();
        return savedObject;
    }

}

public class TestJava {

    public void run() {
        String s ="test";
        String ret = (String) RandomHelper.withCastTest(new Randomable<String>(s) {

            @Override
            public String get() {
                return object;
            }
        });

        String ret2 = RandomHelper.withoutCastTest(new Randomable<String>(s) {

            @Override
            public String get() {
                return object;
            }
        }, "test2");

        System.out.println(ret);
        System.out.println(ret2);

    }

    public static void main(String[] args) {
        TestJava test = new TestJava();
        test.run();
    }

}

Edit: Typo in code

Upvotes: 0

Views: 42

Answers (2)

Emerson Cod
Emerson Cod

Reputation: 2090

your abstract class does not implement the generic interface

Randomable<E> implements RandomInterface<E>

is missing.

Also your implementations can not return Object, but must return String as type

Upvotes: 1

fluminis
fluminis

Reputation: 4059

You just need to add the parameter <E> after implements RandomInterface in

public abstract class Randomable<E> implements RandomInterface<E> {

Then you need to change : (note the return type of get methods)

    String ret = RandomHelper.withCastTest(new Randomable<String>(s) {

        @Override
        public String get() {
            return s;
        }
    });

    String ret2 = RandomHelper.withoutCastTest(new Randomable<String>(s) {
        @Override
        public String get() {
            return s;
        }
    }, "test2");

Upvotes: 1

Related Questions