user69874
user69874

Reputation: 155

How to use Function with primitive return or argument type in Java?

In Java 8, there is a feature akin to a function-pointer(java.util.function.Function). It is usually used like this: Function<LookupKey,LookupResult>, however, there is a problem if the method returns a primitive type. Function<ArgType,Void.TYPE> doesn't work, it fails to compile with a very confusing error message("cannot find symbol Void.TYPE"). I would rather avoid changing my method to return an Object just to pass null as the result.

Upvotes: 4

Views: 3614

Answers (3)

Harmlezz
Harmlezz

Reputation: 8068

If your function should not return a value, consider using Consumer<T> instead.

If your function should return an ìnt or long consider using ToIntFunction<T> or ToLongFunction<T> which returns primitive types.

If your function should return boolean, then use Predicate<T>.

And finally, if you need to consume an primitive type but want to return a reference type use IntFunction<T> or LongFunction<T>.

To complete the list: IntToLongFunction, LongToIntFunction, IntUnaryOperator and LongUnaryOperator support primitive types to be consumed and returned.

Upvotes: 16

Gerald M&#252;cke
Gerald M&#252;cke

Reputation: 11132

As mentioned by Harmlezz, you should use a ToIntFunction<T> or any other of the "toPrimitiveType" functions and if your method returns no value, use a Consumer<T>.

But for the sake of completion - and out of curiosity what is possible:

As you noticed, there is a Void class in java, and you can define a Function returning Void:

Function<Long,Void> f = i -> {
        System.out.println(i);
        return ???;
    };

Of course you can just return null, but that would cause nasty NullPointerExceptions, for example this won't work

f.apply(123L).toString();

You can not create Void instances - unless you use reflection :)

So let's create a VOID literal (assuming, it's not forbidden by security settings)

static Void VOID;

static {
    try {
        Constructor<Void> vc = Void.class.getDeclaredConstructor();
        vc.setAccessible(true);
        VOID = vc.newInstance();
    } catch (Exception e) {
        throw new Error(e);
    }
}

Now you just return this literal in your function:

Function<Long,Void> f = i -> {
        System.out.println(i);
        return VOID;
    };

And the function application would result in a non-null result of type Void

System.out.println(f.apply(123L).getClass());

prints out:

123
class java.lang.Void

However, NEVER use that in your code unless you want to demonstrate pointless edge cases ;)

Upvotes: 1

Joni
Joni

Reputation: 111239

Use the Consumer interface instead. A procedure that doesn't return anything is not a "function."

Upvotes: 3

Related Questions