Method References in Java - Quiz

Total: 17 questions

1. 

What are method references?

Lambda expressions are used to create anonymous methods. In cases when a lambda expression only invokes one existing method, it is better to refer to the existing method by name. Method references gives the possibility to do this. They are compact lambda expressions for methods that already have a name.

2. 

Types of method references.

There are four types of method references:

  • Reference to a static method
  • Reference to an instance method of a particular object
  • Reference to an instance method of an arbitrary object of a particular type
  • Reference to a constructor
3. 

Syntax of a reference to a static method.

ContainingClass::staticMethodName

4. 

Syntax of a reference to an instance method of a particular object.

containingObject::instanceMethodName

5. 

Syntax of a reference to an instance method of an arbitrary object of a particular type.

ContainingType::methodName

6. 

Syntax of a reference to a constructor.

ClassName::new

 

7. 

Refactor example using method reference:

Function<String, Boolean> function = e -> Boolean.valueOf(e);
System.out.println(function.apply("TRUE"));
Function<String, Boolean> function = Boolean::valueOf;
System.out.println(function.apply("TRUE"));
8. 

When reference to an instance method of a particular object can be used?

This type of method references is used when a lambda expression calls a method of an external object that already exists.

9. 

Refactor an example:

Consumer<String> consumer = e -> System.out.println(e);
consumer.accept("OCPJP 8");
Consumer<String> consumer = System.out::println;
consumer.accept("OCPJP 8");
10. 

Refactor an example:

Integer integer = new Integer(5);
Supplier<String> supplier = () -> integer.toString();
System.out.println(supplier.get());
Integer integer = new Integer(5);
Supplier<String> supplier = integer::toString;
System.out.println(supplier.get());
11. 

Refactor an example:

IntFunction<String> function = i -> String.valueOf(i);
System.out.println(function.apply(450));
IntFunction<String> function = String::valueOf;
System.out.println(function.apply(450));
12. 

Refactor example:

Function<String, String> function = s -> s.toLowerCase();
System.out.println(function.apply("OCPJP 8"));
Function<String, String> function = String::toLowerCase;
System.out.println(function.apply("OCPJP 8"));
13. 

Refactor example:

Function<String, Integer> function = (d) -> new Integer(d);
System.out.println(function.apply("4"));
Function<String, Integer> function = Integer::new;
System.out.println(function.apply("4"));
14. 

If a class declares multiple constructors, how the compiler choose one for constructor reference?

The compiler checks the type of the functional interface with all of the constructors and choose the best match.

15. 

When is the expression to the left of the :: operator evaluated?

Once, at the moment the method reference is created — not on every call. That is why this code fails on the second line:

String s = null;
Supplier<Integer> supplier = s::length; // NullPointerException right here
System.out.println(supplier.get());      // never reached

The equivalent lambda () -> s.length() behaves differently: the receiver is read on every call, so the exception happens inside supplier.get(). For the same reason System.out::println captures the output stream that was installed when the reference was created, and a later System.setOut(...) does not affect it.

16. 

When can a lambda expression NOT be replaced with a method reference?

A method reference replaces only a lambda that does nothing but call one existing method or constructor and passes its own parameters to it unchanged and in the same order. It cannot be used when:

  • the lambda body contains several operations, a condition or arithmetic;
  • the argument order has to be swapped: (a, b) -> f(b, a);
  • an argument or a constant has to be supplied: s -> s.substring(1);
  • the call is ambiguous and the compiler cannot pick a method (error: reference to ... is ambiguous).
Function<String, String> ok   = String::trim;            // compiles
Function<String, String> fail = String::substring;       // does not compile
Function<String, String> okLambda = s -> s.substring(1); // keep the lambda

Rule of thumb: use a method reference when the lambda looks like x -> something(x) or x -> x.something().

17. 

How do you create an array with a constructor reference?

Use the Type[]::new form, which is equivalent to the lambda size -> new Type[size]:

IntFunction<String[]> arrayCreator = String[]::new;
String[] empty = arrayCreator.apply(3);

String[] result = Stream.of("a", "b", "c")
                        .toArray(String[]::new);
System.out.println(result.length); // 3

It is most often used with Stream.toArray(): with the String[]::new argument the method returns String[], while toArray() without an argument returns Object[]. This is a special form of a constructor reference, not a fifth kind of method reference.

Page 1 of 1