Generic method reference type specifying before/after :: operator

java generic method return type
c# generic method multiple types
java generic method parameter
c# generic method where t multiple types
java generic method example
generic method c#
java generics question mark
java generic method parameter extends

What is the difference between the following method references,

BiPredicate<List<String>,String> contains1 = List<String>::contains;

BiPredicate<List<String>,String> contains2 = List::<String>contains;

BiPredicate<List<String>,String> contains3 = List<String>::<String>contains;

Do the cases have special names? Is there any example similar to the usage?

First of all, that is called a type witness (in the official Oracle Tutorial) or TypeArguments (in the JLS Sec 15.12) and you are effectively helping the compiler with such constructs.

One example:

private static void test(Callable<Object> call) {

}

private static void test(Runnable run) {

}

static class Gen<T> {

}

And call it via test(Gen::new); (this will fail, never mind why), but the point is that you add a type witness to help the compiler, so this would work

test(Gen<String>::new);

So when you write List<String>, you have added a type witness for the target type - List that is; in the second case you are adding one for the method contains - but it's not generic, so it is ignored.

where (generic type constraint), The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local Before C# 7.3, Enum, Delegate, and MulticastDelegate were also to create an instance of a type parameter using the new operator. Generic method reference type specifying before/after :: operator What is the difference between the following method references, BiPredicate<List<String>,String> contains1 = List<String>::contains; BiPredicate<List<String>,String>

In:

BiPredicate<List<String>, String> contains2 = List::<String>contains;

<String> is a type argument to a non-generic List.contains method1.

While in:

BiPredicate<List<String>, String> contains1 = List<String>::contains;

<String> is a type argument to a List.


1 - In this particular case a type argument is ignored according to the JLS §15.12.2.1:

A non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. In such a case, the type arguments will simply be ignored.

The Basics of Java Generics, A quick and practical overview of method references in Java. only to Integer type i.e. we specify the type that will be held inside the list. Generic methods have a type parameter (the diamond operator before the return type of the method declaration; Type parameters would change after compilation:. We've used the :: operator as shorthand for lambdas calling a specific method – by name. And the end, result is of course even more readable syntax. 3. How Does It Work? Very simply put, when we are using a method reference – the target reference is placed before the delimiter :: and the name of the method is provided after it.

Here's what Intellij tells me about them:

BiPredicate<List<String>, String> contains1 = List<String>::contains;

Explicit type arguments can be inferred

BiPredicate<List<String>, String> contains2 = List::<String>contains;

Type arguments are redundant for the non-generic method reference

If you were to split these up into their respective lambda functions, I believe you'd see the following:

BiPredicate<List<String>, String> contains1 = (List<String> strings, String o) -> strings.contains(o);
BiPredicate<List<String>, String> contains2 = (strings, o) -> strings.<String>contains(o);

As we know, (List<String> strings, String o) can be replaced by (strings, o) and <String> on the second line is unneeded (as String#contains isn't generic), so it's safe to assume that both method references are equivalent.

Time To Really Learn Generics: A Java 8 Perspective, Java introduced generic methods and classes back in 2004 with so-called diamond operator used in both the previous code samples. The emptyList method uses it to specify the contained type in the List . You can't however, add an Object reference to a List<String> , which forEach(output::add); }. Ending vector value, specified as a real numeric scalar. k is the last value in the vector only when the increment lines up to exactly land on k.For example, the vector 0:5 includes 5 as the last value, but 0:0.3:1 does not include the value 1 as the last value since the increment does not line up with the endpoint.

Method References (The Java™ Tutorials > Learning the Java , Kinds of Method References. There are four kinds of method references: Kind, Example. Reference to a static method, ContainingClass::staticMethodName. <String> is a type argument to a non-generic List.contains method 1. <String> List.contains. While in: BiPredicate<List<String>, String> contains1 = List<String>::contains; <String> is a type argument to a List. <String> List. 1 - In this particular case a type argument is ignored according to the JLS §15.12.2.1:

Chapter 15. Expressions, This chapter specifies the meanings of expressions and the rules for their This rule is introduced because inference of a generic class's type arguments may If TypeArguments is present immediately after new , or immediately before ( The method reference expression has the form ReferenceType :: [TypeArguments]  T/F If a derived class reference is assigned to a base class variable, the variable must be cast back to the derived class before any derived class methods can be called with it.

11. Method References, A method reference to an instance method of an object of a particular type we use the :: operator, and that we don't pass arguments to the method reference. before the :: operator and the name of the method after it without arguments. C. When using method references, you don't have to specify the arguments the  The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.

Comments
  • Related: stackoverflow.com/questions/31245127/…. Seems the first syntax specifies type argument for List, whereas the second specifies type argument for contains (unnecessary in this case because the method is not generic)
  • And, of course, BiPredicate<List<String>,String> contains1 = List<String>::<String>contains;.
  • As a related side-note, and a partial explanation: it's legal to supply type arguments to a non-generic method, such as list.<Number>contains("foo"). They're just ignored. (As for why the JLS authors chose to allow it, though, I don't know.)
  • @Radiodef I don't know its exact reason but I suspect that you are Herbert Schildt
  • @snr Why is it legal to supply type arguments to a non-generic method? You can find the answer here.
  • Where does the term "type witness" come from? I can't find it in the language spec.
  • @AndyTurner docs.oracle.com/javase/tutorial/java/generics/… search for "type witness", I was not saying it's in the JLS (might be, not sure)
  • @Lino the official java tutorial calls it that way, I'll stick to that :)
  • The word "witness" doesn't appear in JLS (9, at least). They are simply called TypeArguments there.
  • Is there any difference btw type parameter and type argument terms in this context? If yes, what is this?
  • Yes, there is a difference. E in List<E> is a type parameter and the String in List<String> is a type argument. You can think of a generic type invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing a type argument - String in this case - to the List itself (source).