0

Confused on this one (The error is on assigning f2 = func1).

  1. Why is creating func1 not an error as we are using Number.shortValue() but defined a lower bound as a Number?
  2. If func1 can be created this way then why cannot it be assigned to f2?

Thanks for your help.

    Function<? super Number, ? extends String> func1 = obj -> String.valueOf(obj.shortValue());
    Function<Integer, String> f2 = func1;

The error is:

Incompatible types. Found: 'java.util.function.Function<capture<? super java.lang.Number>,capture<? extends java.lang.String>>', required: 'java.util.function.Function<java.lang.Integer,java.lang.String>'
Khanna111
  • 3,627
  • 1
  • 23
  • 25
  • Because func1's type is not compatible with f2's – Maurice Perry Jul 20 '23 at 06:07
  • 1
    `? super Number` means any class that is `Number` or a **super** class of it, i.e. `Object`. What you want ist `? extends Number` to instantiate **sub** classes, i.e. `Integer`. – Sascha Jul 20 '23 at 09:20
  • Look at this question for more: https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java – Sascha Jul 20 '23 at 09:24
  • @Sascha no: `Function extends Number, ...>` is a `Function` that accepts a specific but unknown subclass of `Number`. You wouldn't be able to pass anything into such a `Function` except for literal `null`. – Andy Turner Jul 20 '23 at 18:57
  • @AndyTurner I misread the question. – Sascha Jul 24 '23 at 08:01

1 Answers1

1
Function<? super Number, ? extends String> func1 = obj -> String.valueOf(obj.shortValue());
  1. Why is creating func1 not an error as we are using Number.shortValue() but defined a lower bound as a Number?

The right-hand side of this assignment is a Function<Number, String>. You're allowed to assign that to a variable of type Function<? super Number, ? extends String> because that's a more general type; but you won't be able to pass anything into it which isn't a Number (or literal null), and so anything you are allowed to pass to it will have a shortValue() method.

Function<? super Number, ...> means "a Function that it's safe to pass a Number to; it's not "a Function that you can pass any superclass of Number to".

Function<Integer, String> f2 = func1;
  1. If func1 can be created this way then why cannot it be assigned to f2?

As I stated above, a Function<Number, String> is a Function<? super Number, ? extends String>; the converse is not true.

It's the same as "all apples are fruit; not all fruit are apples".

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 1
    I thought I understood type inference and type parameter bounds pretty well, but I guess I never before saw a lower bound factor into type inference in this way. It feels wrong that the inferred type is not `Function`, leading to an error on account of `Object` not having a `shortValue()` method. – John Bollinger Jul 20 '23 at 17:54
  • That was my confusion also – Khanna111 Jul 21 '23 at 06:34