1

I have the following class:

package query;

public class Predicate<T> {

    private String operand1; 
    private String operator; 
    private T operand2; 
    private Class<T> classType; 

    public Predicate(String operand1, T operand2, Class<T> classType){
        this(operand1, "=", operand2, classType); 
    }

    public Predicate(String operand1, String operator, T operand2, Class<T> classType){
        this.operand1 = operand1; 
        this.operator = operator; 
        this.operand2 = operand2; 
        this.classType = classType; 
    }

    public String getOperand1() {
        return operand1;
    }

    public String getOperator() {
        return operator;
    }

    public T getOperand2() {
        return operand2;
    }

    public Class<T> getClassType() {
        return classType;
    }

    @Override
    public String toString() {
        return operand1 + " " + operator + " ?"; 
    }
}

The following line compiles fine:

Predicate<String> p1 = new Predicate<>("given_name", "=", "Kim", String.class); 

However, the following does not:

Predicate<Integer> p1 = new Predicate<>("id", "=", "1", Integer.class); 

The compiler mentions: Cannot infer type arguments for Predicate<>

What is wrong / how can solve this?

html_programmer
  • 18,126
  • 18
  • 85
  • 158
  • A little curious: why are you passing in the class explicitly instead of getting it from the `operand2` argument? – Mike 'Pomax' Kamermans Jan 24 '16 at 18:26
  • @Mike'Pomax'Kamermans I set the following property: `private Class classType;` because I need it later on. I'm not sure how to extract the information from the object. – html_programmer Jan 24 '16 at 18:39
  • can't you just use `operand2.getClass()`? (if it's an int, autoboxing will give you `Integer`) – Mike 'Pomax' Kamermans Jan 24 '16 at 18:48
  • I tried it, but the compiler requests an explicit cast. The problem is that if I do, I get a warning that I'm dealing with an unchecked cast. But the invocation is cleaner, isn't it? Perhaps I should go with this. – html_programmer Jan 24 '16 at 18:56
  • what about a getClass, check for identity on T, if it checks out, you can safely cast. – Mike 'Pomax' Kamermans Jan 24 '16 at 19:07
  • How would you check the generic type at runtime? I'm not sure it's possible... – html_programmer Jan 24 '16 at 19:18
  • you mean compile time? Because getClass() *only* works at runtime. It checks the instance for its current class, returns it, you can then check whether `T` and that class have common ground, if it does, the cast is guaranteed safe, if not, your classtype will be null. Of course, this is assuming you need to *know* the classtype. Not sure I can think of a reason for that. (if you're writing an AST, for instance, you have subclasses for all the types you need to support, you wouldn't use generics) – Mike 'Pomax' Kamermans Jan 24 '16 at 19:34
  • You're right, @compile time. SO doesn't really like extended chat, so in case you're interested, I've added a new question here: http://stackoverflow.com/questions/34980619/why-does-the-compiler-request-a-cast – html_programmer Jan 24 '16 at 19:48

1 Answers1

7

"1" is a String and incompatible with Integer.class

new Predicate<>("id", "=", 1, Integer.class)

should be ok

or

new Predicate<>("id", "=", "1", String.class)
Reimeus
  • 158,255
  • 15
  • 216
  • 276