Haven't touched Java 8+ in a bit, but I remember Function2, Function3, Function4<P,Q,R,S> etc when referring to a closure. Streams used a ton of specializations like ToDoubleBiFunction<P, Q> meaning (P p, Q q) -> double.
I wonder if such contracts are are solved now like in other languages with typed function references/pointers - C++/Go/etc (syntactic sugar is enough, doesn't have to be variadic generics). I remember 'var' was introduced so I suppose that worked if the closure type could be inferred.