Overloading methods with Suppliers as parameters

As I was overloading a method for a class I was making I noticed that the compiler didn’t seem to happy that I used the parameters Supplier<Boolean> and String for one method and Supplier<Double> and String for the other. I think for this case I can use BooleanSupplier and DoubleSupplier, but is there any other way, for example, when using suppliers with other classes, to overload a method with Suppliers of different types?

No, it is not possible to overload generics in this way in Java. See https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotOverload

3 Likes

Whenever you are using primitives, you should be using the non generic interface provided such as BooleanSupplier, IntSupplier, LongSupplier etc. unless you need null as a valid value.

If you do need to overload methods that take suppliers for non generic things, you can create your own custom functional interfaces. That’s all the suppliers are, they’re just basic interfaces with a single method.

1 Like

I never understood why you need BooleanSupplier instead of Supplier<Boolean>, etc.

1 Like

Because any object is Java can be null, you are able to pass null to Supplier. There are also a few cases where its better to use a BooleanSupplier when boolean isn’t converted to Boolean correctly.

I’m sure there’s a better explanation out there somewhere.

BooleanSupplier is a specialization to work with primitive boolean types. Supplier has to use the more memory-inefficient boxed type

1 Like

Supplier<Boolean> is the boxed version. The function signature is T get() which turns into Boolean get().

BooleanSupplier is the primitive version. The function signature is directly boolean get(). Note the lowercase boolean.

Supplier<Boolean> allows null as a value and also allows you to mix with other types that extends Object. BooleanSupplier uses less amount of memory and does not require a pointer lookup, and it’s the way to go if you use it a lot and care about efficiency.

2 Likes

So, answering the main question in the OP - the reason that you can’t have Supplier<X> and Supplier<Y> overloads of the same function, is due to type erasure. The way Java is compiled, it effectively converts each of those to the same class Supplier, and everywhere the generic parameter is used it replaces them with casts to and from Object.

Because of this, you’re effectively making two overloads of Supplier, which don’t have any other information to distinguish.

This is what Peter Johnson’s link explains, sorry I missed that - but I have a small explanation of what type erasure is.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.