4

I saw a question about criteriaBuilder and came up with this question...

What does it mean from.<Integer> get("...?

I've never seen a point before of the expression <Integer>.

Could somebody show me an example?

Link: Compile error when using CriteriaBuilder

Code:

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();
}

Thanks!

Community
  • 1
  • 1
Braian
  • 185
  • 1
  • 2
  • 8

3 Answers3

4

This is a call to a generic method with Integer passed in as a type parameter.

See here:

Java-syntax for explicitly specifiying generic arguments in method calls

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12

Community
  • 1
  • 1
peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • As far as I know Java infers them whenever it can do so, are there any reasons why it would not be able to do so? (In this case, or in general, maybe some Java versions are worse at it?) – skiwi Jan 23 '14 at 20:32
  • This is when you specify it explicitly. – peter.petrov Jan 23 '14 at 20:34
  • Maybe you should post how whole the class Root looks like. I guess you would get more concrete answers this way. – peter.petrov Jan 23 '14 at 20:36
  • @skiwi if by "some Java versions" you mean "some implementations", there shouldn't be any difference from one implementation to the next, because the type inference rules are spelled out by the Java Language Specification. – ajb Jan 23 '14 at 20:46
  • @ajb I more meant Java 5, 6, 7, 8, etc. Especially since the code seems to come from a company (or just example code), it is not unreasonable ot think they are still using Java 5 or 6. – skiwi Jan 23 '14 at 20:51
2

The angle brackets are for Java generics. In most cases, the type of the generic can be inferred, but not always. See Type Inference for a discussion of this topic. The example they use is:

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

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

Apparently in Java 8, this is no longer an issue since the compiler will infer types from method arguments as well.

tskuzzy
  • 35,812
  • 14
  • 73
  • 140
0

From Java Generics and Collections,

List<Integer> ints = Lists.<Integer>toList(); // first example
List<Object> objs = Lists.<Object>toList(1, "two"); // second example
  1. In the first example, without the type parameter there is too little information for the type inference algorithm used by Sun's compiler to infer the correct type. It infers that the argument to toList is an empty array of an arbitrary generic type rather than an empty array of integers, and this triggers the unchecked warning described earlier. (The Eclipse compiler uses a different inference algorithm, and compiles the same line correctly without the explicit parameter.)
  2. In the second example, without the type parameter there is too much information for the type inference algorithm to infer the correct type. You might think that Object is the only type that an integer and a string have in common, but in fact they also both implement the interfaces Serializable and Comparable. The type inference algorithm cannot choose which of these three is the correct type.

In general, the following rule of thumb suffices:

In a call to a generic method, if there are one or more arguments that correspond to a type parameter and they all have the same type then the type parameter may be inferred; if there are no arguments that correspond to the type parameter or the arguments belong to different subtypes of the intended type then the type parameter must be given explicitly.

Some points for passing type parameter

When a type parameter is passed to a generic method invocation, it appears in angle brackets to the left, just as in the method declaration.

The Java grammar requires that type parameters may appear only in method invocations that use a dotted form. Even if the method toList is defined in the same class that invokes the code, we cannot shorten it as follows:

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

This is illegal because it will confuse the parser.

Prateek
  • 12,014
  • 12
  • 60
  • 81