1

I'm having a hard time giving this question a proper title, but I've been reading through some source code and found the following snippets of code

return new IdpResponse(
    in.<User>readParcelable(User.class.getClassLoader()), // <-- x.<y>function(...)
    in.readString(),
    in.readString(),
    in.readInt() == 1,
    (FirebaseUiException) in.readSerializable(),
    in.<AuthCredential>readParcelable(AuthCredential.class.getClassLoader()) // <-- x.<y>function(...)
);

from https://github.com/firebase/FirebaseUI-Android/.../IdpResponse.java

as well as

setResult(Resource.<IdpResponse>forLoading());

from https://github.com/firebase/FirebaseUI-Android/.../SmartLockHandler.java

What is this called and what does it do? It looks almost like a cast for the function result.

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
Daniel F
  • 13,684
  • 11
  • 87
  • 116
  • 2
    it's a function with a template, have a look at this https://stackoverflow.com/questions/30939425/java-template-function – Alberto Sinigaglia Jan 12 '20 at 21:41
  • 3
    Are you familiar with [generic methods](https://docs.oracle.com/javase/tutorial/java/generics/methods.html)? With syntax `.someGenericMethod()` you just explicitly provide specific type which generic type should represent in current method invocation. – Pshemo Jan 12 '20 at 21:49
  • 1
    @Pshemo - Thanks, that's it. So like function templates in C++. – Daniel F Jan 12 '20 at 21:50
  • 2
    It's commonly called a `type witness`, it's needed when the type inference can't figure out the type on its own. – kaqqao Jan 13 '20 at 17:38

1 Answers1

1

To answer your questions:

  1. As AlbertoSinigaglia and Pshemo both said, the constructs you asked about:

    in.<User>readParcelable(User.class.getClassLoader()

    and

    in.<AuthCredential>readParcelable(AuthCredential.class.getClassLoader()

are both examples of a "function with a template".

  1. You can read more details in Oracle's Java tutorials:

  2. Quoting from the "Type Inference" tutorial:

Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.

Consider the following example, BoxDemo, which requires the Box class:

public class BoxDemo {

  public static <U> void addBox(U u, 
      java.util.List<Box<U>> boxes) {
    Box<U> box = new Box<>();
    box.set(u);
    boxes.add(box);
  }

  public static <U> void outputBoxes(java.util.List<Box<U>> boxes) {
    int counter = 0;
    for (Box<U> box: boxes) {
      U boxContents = box.get();
      System.out.println("Box #" + counter + " contains [" +
             boxContents.toString() + "]");
      counter++;
    }
  }

  public static void main(String[] args) {
    java.util.ArrayList<Box<Integer>> listOfIntegerBoxes =
      new java.util.ArrayList<>();
    BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
    BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);
    BoxDemo.addBox(Integer.valueOf(30), listOfIntegerBoxes);
    BoxDemo.outputBoxes(listOfIntegerBoxes);
  }
}

The generic method addBox defines one type parameter named U. Generally, a Java compiler can infer the type parameters of a generic method call. Consequently, in most cases, you do not have to specify them. For example, to invoke the generic method addBox, you can specify the type parameter with a type witness as follows:

BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);

Alternatively, if you omit the type witness,a Java compiler automatically infers (from the method's arguments) that the type parameter is Integer:

BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);
  1. Finally, regarding "It looks almost like a cast for the function result.":

Java - Generics vs Casting Objects

The point of generics is NOT to allow a class to use different types at the same time.

Generics allow you to define/restrict the type used by an instance of an object.

The idea behind generics is to eliminate the need to cast.

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
  • 2
    *"function with a template"*? No, it's called a [***generic method***](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4), not "function", not "template". – Andreas Jan 12 '20 at 22:18
  • Thank you for providing the terminology used in the Java spec (after all, the OP's question was "what is it called?"). Informally, however, I have no qualms with saying it's *like* a "function template" (as AlbertoSinigaglia called it), or even "subroutine template" (terminoligy free of ANY Java connotations). I *hope* I at least successfully conveyed the *concepts* DanielF was asking about. – FoggyDay Jan 13 '20 at 21:17