Curiously Recurring Template Pattern (CRTP) implementation I'm implementing Curiously Recurring Template Pattern(CRTP) in Java as follows.

The Interface:

/**
 * Reason for the generic Value&lt;T extends Value&gt;
 * Value&lt;IntValue&gt; x; // legal, IntValue implements Value interface so allowed
 * Value&lt;Integer&gt; x;  // illegal, does not implement Value interface  
 */
@SuppressWarnings("rawtypes")
public interface Value&lt;T extends Value&gt; {
    T deepCopy();
}


Classes implementing it:

public class IntValue implements Value&lt;IntValue&gt; {
    Integer value;

    public IntValue(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }

    @Override
    public IntValue deepCopy() {
        return new IntValue(value);
    }
}
/**
* // Valid
* List&lt;IntValue&gt; ints = Arrays.asList(new IntValue(Integer.valueOf(5)));
* ArrayValue&lt;IntValue&gt; arr = new ArrayValue&lt;&gt;(ints);
*
* // Invalid
* List&lt;Integer&gt; ints = Arrays.asList(Integer.valueOf(5));
* ArrayValue&lt;Integer&gt; arr = new ArrayValue&lt;&gt;(ints); 
*/
@SuppressWarnings("rawtypes")
public class ArrayValue&lt;T extends Value&gt; implements Value&lt;ArrayValue&lt;T&gt;&gt; {

    List&lt;T&gt; values;

    public ArrayValue() {
        this(new ArrayList&lt;&gt;());
    }

    public ArrayValue(List&lt;T&gt; values) {
        this.values = values;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ArrayValue&lt;T&gt; deepCopy() {
        List&lt;? super Value&gt; copyValues = new ArrayList&lt;&gt;();
        values.forEach(value -&gt; copyValues.add(value.deepCopy()));
        return new ArrayValue&lt;T&gt;((List&lt;T&gt;) copyValues);
    }
}

//Static Function using the interface
@SuppressWarnings("rawtypes")
public static Value sub(Value a, Value b) 
{
    if(a instanceof IntValue &amp;&amp; b instanceof IntValue)
    {
        return new IntValue( ((IntValue)a).getValue() - ((IntValue)b).getValue());
    }
    else
    {
        throw new TypeMismatchException("Operation not supported");
    }
    return NullValue.NULL_VALUE;
}


However I have to suppress warnings multiple times throughout the implementation.

Are the uses of suppress annotation justified?
As far I can tell this doesn't generate any warnings:

class IntValue implements Value&lt;IntValue&gt; {

    Integer value;

    public IntValue(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }

    @Override
    public IntValue deepCopy() {
        return new IntValue(value);
    }
}


class ArrayValue&lt;T extends Value&lt;T&gt;&gt; implements Value&lt;ArrayValue&lt;T&gt;&gt; {

    List&lt;T&gt; values;

    public ArrayValue() {
        this(new ArrayList&lt;&gt;());
    }

    public ArrayValue(List&lt;T&gt; values) {
        this.values = values;
    }

    @Override
    public ArrayValue&lt;T&gt; deepCopy() {
        List&lt;T&gt; copyValues = new ArrayList&lt;&gt;();
        values.forEach(value -&gt; copyValues.add(value.deepCopy()));
        return new ArrayValue&lt;&gt;(copyValues);
    }
}


But it makes more sense to do it without CRTP:

public interface Value&lt;T&gt; {
    Value&lt;T&gt; deepCopy();
    T getValue();
}


class IntValue implements Value&lt;Integer&gt; {

    Integer value;

    public IntValue(Integer value) {
        this.value = value;
    }

    @Override
    public Integer getValue() {
        return value;
    }

    @Override
    public IntValue deepCopy() {
        return new IntValue(value);
    }
}


class ArrayValue&lt;T&gt; implements Value&lt;List&lt;Value&lt;T&gt;&gt;&gt; {

    List&lt;Value&lt;T&gt;&gt; values;

    public ArrayValue() {
        this(new ArrayList&lt;&gt;());
    }

    public ArrayValue(List&lt;Value&lt;T&gt;&gt; values) {
        this.values = values;
    }

    @Override
    public ArrayValue&lt;T&gt; deepCopy() {
        List&lt;Value&lt;T&gt;&gt; copyValues = new ArrayList&lt;&gt;();
        values.forEach(value -&gt; copyValues.add(value.deepCopy()));
        return new ArrayValue&lt;&gt;(copyValues);
    }

    @Override
    public List&lt;Value&lt;T&gt;&gt; getValue() {
        return values;
    }
}

class X {

    public static Value sub(Value&lt;Integer&gt; a, Value&lt;Integer&gt; b) {
         return new IntValue(b.getValue() - b.getValue());
    }
}