Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yet another Java generics "incompatible types" compilation error

I was writing some code and came across a incompatible types compilation error. This is what I have:

public interface Expression<T> {
    int getArity();
    T evaluate();
}

public abstract class Value<T> implements Expression<T> {
    @Override
    public final int getArity() { return 0; }
}

public final class Constant<T> extends Value<T> {
    private final T value;

    /** Parameter constructor of objects of class Constant. */
    public Constant(T val) {
        value = val;
    }

    /** Copy constructor of objects of class Constant. */
    private Constant(Constant instance) {
        value = instance.evaluate();    // Error here.
    }

    @Override
    public T evaluate() { return value; }
}

I thought I wasn't declaring generics correctly when using inheritance, so I checked Oracle's tutorial, in which they write

interface PayloadList<E,P> extends List<E>

The above declaration uses the same generic type E, which is what I want to accomplish in my example. It seems to be assuming that the T from Constant<T> is different from the one from Value<T>. Otherwise it should be able to merge both T and see it's the same type. How can I correctly implement what I'm trying to achieve?

(Ie, a constant of something is a value of something, which is an expression of the same something)

like image 784
afsantos Avatar asked Dec 06 '22 07:12

afsantos


1 Answers

Your instance variable is defined as Constant instance;

If you don't specify your generic on your variable, the generic type will automatically be Object, and the type Object is different from T.

You have to use

private Constant(Constant<T> instance)

instead of

private Constant(Constant instance)

because this would be the same as private Constant(Constant<Object> instance)

like image 164
bpoiss Avatar answered Dec 15 '22 00:12

bpoiss