“from.<Integer>”是什么意思?

4

我看到一个关于criteriaBuilder的问题,引发了这个问题...

什么意思是from.<Integer> get("...?

我以前从未见过表达式<Integer>中的点。

有人能给我展示一个例子吗?

链接:使用CriteriaBuilder时编译错误

代码:

public List<BankAccount> findWithBalance(int amount) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class);
    Root<BankAccount> from = cq.from(BankAccount.class);

    ParameterExpression<Integer> balance = cb.parameter(Integer.class);
    cq.select(from);

    //Here is the trick!
    Predicate predicate = cb.gt(from.<Integer> get("balance"), balance);

    cq.where(predicate);
    cq.orderBy(cb.asc(from.get("ownerName")));

    TypedQuery<BankAccount> query = em.createQuery(cq);

    query.setParameter(balance, amount);

    return query.getResultList();
}

谢谢!

3个回答

4

据我所知,Java会在可以推断类型的情况下进行推断,有没有任何原因它不能这样做?(在这种情况下或一般情况下,也许某些Java版本不擅长此项功能?) - skiwi
这是当您明确指定时的情况。 - peter.petrov
也许你应该发布整个 Root<BankAccount> 类的代码,这样你会得到更具体的答案。 - peter.petrov
@skiwi 如果你所说的“一些Java版本”指的是“一些实现”,那么从一个实现到另一个实现都不应该有任何区别,因为类型推断规则已经在Java语言规范中明确说明了。 - ajb
@ajb 我的意思是Java 5、6、7、8等版本。特别是代码似乎来自一家公司(或者只是示例代码),认为他们仍在使用Java 5或6并不是不合理的。 - skiwi

2

尖括号用于Java泛型。在大多数情况下,可以推断出泛型的类型,但并非总是如此。请参见类型推断以了解此主题的讨论。他们使用的示例是:

void processStringList(List<String> stringList) {
    // process stringList
}

processStringList(Collections.emptyList()); // Compile error!
processStringList(Collections.<String>emptyList());  // Ok!

显然,在Java 8中,这不再是一个问题,因为编译器也会从方法参数中推断类型。


0

来自Java泛型和集合

List<Integer> ints = Lists.<Integer>toList(); // first example
List<Object> objs = Lists.<Object>toList(1, "two"); // second example
  1. 在第一个例子中,如果没有类型参数,则提供的信息太少,无法让Sun编译器使用的类型推断算法推断出正确的类型。它会推断toList的参数是一个任意泛型类型的空数组,而不是整数的空数组,这会触发前面描述的未经检查的警告。(Eclipse编译器使用不同的推断算法,并且可以在没有显式参数的情况下正确编译相同的行。)
  2. 在第二个例子中,如果没有类型参数,则提供的信息太多,使得类型推断算法无法推断出正确的类型。你可能认为Object是整数和字符串共有的唯一类型,但实际上它们还都实现了Serializable和Comparable接口。类型推断算法无法选择这三种类型中的哪一种是正确的类型。

通常,以下经验法则就足够了:

在调用泛型方法时,如果有一个或多个参数对应于类型参数,并且它们都具有相同的类型,则可以推断出类型参数;如果没有参数对应于类型参数或者这些参数属于预期类型的不同子类型,则必须显式给出类型参数。

传递类型参数的一些要点

当将类型参数传递给泛型方法调用时,它出现在尖括号中,就像在方法声明中一样。

Java语法要求类型参数只能出现在使用点形式的方法调用中。即使toList方法在调用代码所在的同一类中定义,我们也不能缩短它如下:

List<Integer> ints = <Integer>toList(); // compile-time error

这是非法的,因为它会混淆解析器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接