7

我正在使用 Hibernate 验证器并尝试创建一个小实用程序类:

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)?为什么不能指定:

  1. TClassValidator<T>(T)
  2. 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 方法是(这里

4

3 回答 3

8

因为T不是一个值——它只是对编译器的一个提示。JVM 不知道T. 您只能将泛型用作一种类型,以便在编译时进行类型检查。

于 2010-01-15T21:12:31.293 回答
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在运行时得到,但这很容易调试,尽管它不是泛型背后的想法。

于 2010-01-15T21:14:07.063 回答
0

因为ClassValidator需要一个 Class 对象作为其参数,而不是相关类的实例。请记住,您可能可以使用此代码执行您尝试执行的操作:

ClassValidator<? extends T> validator = new ClassValidator<? extends T>(validateMe.getClass());
于 2010-01-15T21:11:36.017 回答