Initialize variable by evaluating lambda directly

Jens :

I am wondering if there is a way to call .apply() or .get() on a lambda function directly in the same expression it is defined. The question came to mind when I wanted to initialize a variable which could be private, but I cannot declare it final because the value is the return value of a function that can throw an exception. As an example, consider Files.size(path):

 final s = Files.size(path);
 // code that uses s

Now, if I want to use a default value for s if there is an exception, I have to add a try/catch, but this is a statement and not an expression:

s = 0;
try {
    s = Files.size();
}
catch (IOException e) {}

 // code that uses s

The obvious solution is to just declare a small helper function that wraps the try/catch, e.g. getFileSizeOrZero. I could also write a generic function that wraps this as a general case. This is nice and descriptive, but a more local function approach whould be better.

In C++, I used lambdas:

const s = []() {
    try {
        return Files.size(path);
    } catch (...) {
        return 0;
    }
}();

so I wondering if this can be done in Java. The best I could come up with was

final int s = new IntSupplier() {
    @Override
    public int getAsInt() {
        try {
            return Files.size(path);
        }
        catch (IOException e) {
            return 0;
        }
    }
 }.getAsInt();

This seems to be quite expressive, so I am hoping that there is some syntac that I don't know enabling

final int s = () -> {
    try {
        return Files.size(path);
    }
    catch (IOException e) {
        return 0;
    }
}.apply();

It seems that the problem is there is no function call operator as in C++, so there has to be a named member function which can be called.

Jack :

You can do this but you need to explicitly cast the anonymous lambda to the correct type. That's because you need to coerce the type of the lambda to the specific functional interface, Java can't guess the final type, eg:

final int x = ((IntSupplier)() -> 5).getAsInt();

If you don't like it you need to store it in a variable:

final IntSupplier xx = () -> 5;
final int x = xx.getAsInt();

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=459537&siteId=1