Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics question - Class<T> vs. T?

I'm using Hibernate validator and trying to create a little util class:

public class DataRecordValidator<T> {
    public void validate(Class<T> clazz, T validateMe) {
        ClassValidator<T> validator = new ClassValidator<T>(clazz);
        InvalidValue[] errors = validator.getInvalidValues(validateMe);
        [...]
    }
}

Question is, why do I need to supply the Class<T> clazz parameter when executing new ClassValidator<T>(clazz)? Why can't you specify:

  1. T as in ClassValidator<T>(T)?
  2. validateMe.getClass() as in ClassValidator<T>(validateMe.getClass())

I get errors when I try to do both options.

Edit: I understand why #1 doesn't work. But I don't get why #2 doesn't work. I currently get this error with #2:

cannot find symbol
symbol  : constructor ClassValidator(java.lang.Class<capture#279 of ? extends java.lang.Object>)
location: class org.hibernate.validator.ClassValidator<T>

Note: Hibernate API method is (here)

like image 847
Marcus Leon Avatar asked Jan 15 '10 21:01

Marcus Leon


2 Answers

Because T is not a value - it's just a hint for the compiler. The JVM has no clue of the T. You can use generics only as a type for the purposes of type checking at compile time.

like image 112
Ondra Žižka Avatar answered Oct 11 '22 04:10

Ondra Žižka


If the validate method is yours, then you can safely skip the Class atribute.

public void validate(T validateMe) {
    ClassValidator<T> validator = 
           new ClassValidator<T>((Class<T>) validateMe.getClass());
    ...
}

But the ClassValidator constructor requires a Class argument.

Using an unsafe cast is not preferred, but in this case it is actually safe if you don't have something like this:

class A {..}
class B extends A {..}

new DataRecordValidator<A>.validate(new B());

If you think you will need to do something like that, include the Class argument in the method. Otherwise you may be getting ClassCastException at runtime, but this is easily debuggable, although it's not quite the idea behind generics.

like image 44
Bozho Avatar answered Oct 11 '22 05:10

Bozho