我正在使用Hibernate验证器并尝试创建一个小类util:
public class DataRecordValidator<T> {
public void validate(Class<T> clazz, T validateMe) {
ClassValidator<T> validator = new ClassValidator<T>(clazz);
InvalidValue[] errors = validator.getInvalidValues(validateMe);
[...]
}
}
问题是,为什么我在执行Class<T> clazz
时需要提供new ClassValidator<T>(clazz)
参数?为什么不指定:
T
和ClassValidator<T>(T)
一样? validateMe.getClass()
与ClassValidator<T>(validateMe.getClass())
当我尝试两种选择时,我会收到错误。
编辑:我理解为什么#1不起作用。但我不明白为什么#2不起作用。我目前在#2中遇到此错误:
cannot find symbol
symbol : constructor ClassValidator(java.lang.Class<capture#279 of ? extends java.lang.Object>)
location: class org.hibernate.validator.ClassValidator<T>
注意:Hibernate API方法是(here)
答案 0 :(得分:8)
因为T
不是值 - 它只是编译器的提示。 JVM没有T
的线索。您只能将泛型用作类型,以便在编译时进行类型检查。
答案 1 :(得分:1)
如果validate
方法属于您,则可以安全地跳过Class
属性。
public void validate(T validateMe) {
ClassValidator<T> validator =
new ClassValidator<T>((Class<T>) validateMe.getClass());
...
}
但是ClassValidator
构造函数需要Class
参数。
使用不安全的演员表不是首选,但在这种情况下,如果您没有这样的话,它实际上是安全的:
class A {..}
class B extends A {..}
new DataRecordValidator<A>.validate(new B());
如果您认为需要执行此类操作,请在方法中包含Class
参数。否则你可能会在运行时获得ClassCastException
,但这很容易调试,虽然它不是泛型背后的想法。
答案 2 :(得分:0)
因为ClassValidator需要Class对象作为其参数,所以不是相关类的实例。请记住,您可以使用此代码执行您要执行的操作:
ClassValidator<? extends T> validator = new ClassValidator<? extends T>(validateMe.getClass());