Java lambda only throwing expression-style instead of statement-style [duplicate]











up vote
16
down vote

favorite
1













This question already has an answer here:




  • Why must throw statements be enclosed with a full code block in a lambda body?

    3 answers




In Java (using Java 8 currently), I can write this and all will compile nice and well:



Supplier<Long> asd = () -> {
throw new RuntimeException();
};


Yet, I cannot write this:



Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(


Does anyone know why Java's implementation does not allow such style (expression lambda) and only the statement/code-block style lambda?



I mean, since the lambda is only throwing the RuntimeException, why isn't the JDK able to infer the lambda expression as:



new Supplier<Long>() {
@Override
public Long get() {
throw new RuntimeException();
}
};


Is this documented somewhere in the specs/docs? Is this added only in JDK > 8?










share|improve this question















marked as duplicate by Ridcully, Heinzi, Mark Rotteveel java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 30 at 15:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
    – JoSSte
    Nov 30 at 12:45






  • 9




    You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
    – Holger
    Nov 30 at 12:48






  • 3




    because throw is not an expression in the same way as return is not an expression perhaps?
    – Joakim Danielson
    Nov 30 at 12:49






  • 1




    Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
    – Heinzi
    Nov 30 at 15:31

















up vote
16
down vote

favorite
1













This question already has an answer here:




  • Why must throw statements be enclosed with a full code block in a lambda body?

    3 answers




In Java (using Java 8 currently), I can write this and all will compile nice and well:



Supplier<Long> asd = () -> {
throw new RuntimeException();
};


Yet, I cannot write this:



Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(


Does anyone know why Java's implementation does not allow such style (expression lambda) and only the statement/code-block style lambda?



I mean, since the lambda is only throwing the RuntimeException, why isn't the JDK able to infer the lambda expression as:



new Supplier<Long>() {
@Override
public Long get() {
throw new RuntimeException();
}
};


Is this documented somewhere in the specs/docs? Is this added only in JDK > 8?










share|improve this question















marked as duplicate by Ridcully, Heinzi, Mark Rotteveel java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 30 at 15:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
    – JoSSte
    Nov 30 at 12:45






  • 9




    You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
    – Holger
    Nov 30 at 12:48






  • 3




    because throw is not an expression in the same way as return is not an expression perhaps?
    – Joakim Danielson
    Nov 30 at 12:49






  • 1




    Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
    – Heinzi
    Nov 30 at 15:31















up vote
16
down vote

favorite
1









up vote
16
down vote

favorite
1






1






This question already has an answer here:




  • Why must throw statements be enclosed with a full code block in a lambda body?

    3 answers




In Java (using Java 8 currently), I can write this and all will compile nice and well:



Supplier<Long> asd = () -> {
throw new RuntimeException();
};


Yet, I cannot write this:



Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(


Does anyone know why Java's implementation does not allow such style (expression lambda) and only the statement/code-block style lambda?



I mean, since the lambda is only throwing the RuntimeException, why isn't the JDK able to infer the lambda expression as:



new Supplier<Long>() {
@Override
public Long get() {
throw new RuntimeException();
}
};


Is this documented somewhere in the specs/docs? Is this added only in JDK > 8?










share|improve this question
















This question already has an answer here:




  • Why must throw statements be enclosed with a full code block in a lambda body?

    3 answers




In Java (using Java 8 currently), I can write this and all will compile nice and well:



Supplier<Long> asd = () -> {
throw new RuntimeException();
};


Yet, I cannot write this:



Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(


Does anyone know why Java's implementation does not allow such style (expression lambda) and only the statement/code-block style lambda?



I mean, since the lambda is only throwing the RuntimeException, why isn't the JDK able to infer the lambda expression as:



new Supplier<Long>() {
@Override
public Long get() {
throw new RuntimeException();
}
};


Is this documented somewhere in the specs/docs? Is this added only in JDK > 8?





This question already has an answer here:




  • Why must throw statements be enclosed with a full code block in a lambda body?

    3 answers








java lambda java-8 throw functional-interface






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 30 at 14:14









Jesse de Bruijne

2,46861327




2,46861327










asked Nov 30 at 12:40









Tamir Nauman

844




844




marked as duplicate by Ridcully, Heinzi, Mark Rotteveel java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 30 at 15:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Ridcully, Heinzi, Mark Rotteveel java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 30 at 15:29


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
    – JoSSte
    Nov 30 at 12:45






  • 9




    You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
    – Holger
    Nov 30 at 12:48






  • 3




    because throw is not an expression in the same way as return is not an expression perhaps?
    – Joakim Danielson
    Nov 30 at 12:49






  • 1




    Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
    – Heinzi
    Nov 30 at 15:31




















  • If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
    – JoSSte
    Nov 30 at 12:45






  • 9




    You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
    – Holger
    Nov 30 at 12:48






  • 3




    because throw is not an expression in the same way as return is not an expression perhaps?
    – Joakim Danielson
    Nov 30 at 12:49






  • 1




    Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
    – Heinzi
    Nov 30 at 15:31


















If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
– JoSSte
Nov 30 at 12:45




If I am not mistaken, the {} surrounding your statement throw new RuntimeException() is an "anonymous function". my guess is that the devs decided that all calls should be in a method, and not in the style you are asking for. this is in no way authoritative, hence the comment, rather than an answer...
– JoSSte
Nov 30 at 12:45




9




9




You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
– Holger
Nov 30 at 12:48




You can not use the expression syntax, because a throw statement is not an expression. As simple as that.
– Holger
Nov 30 at 12:48




3




3




because throw is not an expression in the same way as return is not an expression perhaps?
– Joakim Danielson
Nov 30 at 12:49




because throw is not an expression in the same way as return is not an expression perhaps?
– Joakim Danielson
Nov 30 at 12:49




1




1




Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
– Heinzi
Nov 30 at 15:31






Note: C# got throw expressions in version 7. It might be a good idea to propose such a feature for Java as well (especially if Java ever gets a null coalescing operator, because that seems to be the main use case for throw expressions in C#).
– Heinzi
Nov 30 at 15:31














2 Answers
2






active

oldest

votes

















up vote
22
down vote













From the language spec JLS 15.27.2:




A lambda body is either a single expression or a block (§14.2). 




throw is not a single expression (it's a statement); so you have to use it in a block.






share|improve this answer




























    up vote
    18
    down vote













    What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.



    Supplier<Long> asd = () -> 1L;


    which is equivalent to:



    Supplier<Long> asd = () -> {
    return 1L;
    };


    However, when you write:



    Supplier<Long> asd = () -> throw new RuntimeException();


    It would be translated following which is an invalid lambda:



    Supplier<Long> asd = () -> {
    return throw new RuntimeException(); // invalid expression in Java
    };


    In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.






    share|improve this answer





















    • This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
      – Nick
      Dec 4 at 2:16




















    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    22
    down vote













    From the language spec JLS 15.27.2:




    A lambda body is either a single expression or a block (§14.2). 




    throw is not a single expression (it's a statement); so you have to use it in a block.






    share|improve this answer

























      up vote
      22
      down vote













      From the language spec JLS 15.27.2:




      A lambda body is either a single expression or a block (§14.2). 




      throw is not a single expression (it's a statement); so you have to use it in a block.






      share|improve this answer























        up vote
        22
        down vote










        up vote
        22
        down vote









        From the language spec JLS 15.27.2:




        A lambda body is either a single expression or a block (§14.2). 




        throw is not a single expression (it's a statement); so you have to use it in a block.






        share|improve this answer












        From the language spec JLS 15.27.2:




        A lambda body is either a single expression or a block (§14.2). 




        throw is not a single expression (it's a statement); so you have to use it in a block.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 30 at 12:55









        Andy Turner

        79.2k878131




        79.2k878131
























            up vote
            18
            down vote













            What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.



            Supplier<Long> asd = () -> 1L;


            which is equivalent to:



            Supplier<Long> asd = () -> {
            return 1L;
            };


            However, when you write:



            Supplier<Long> asd = () -> throw new RuntimeException();


            It would be translated following which is an invalid lambda:



            Supplier<Long> asd = () -> {
            return throw new RuntimeException(); // invalid expression in Java
            };


            In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.






            share|improve this answer





















            • This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
              – Nick
              Dec 4 at 2:16

















            up vote
            18
            down vote













            What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.



            Supplier<Long> asd = () -> 1L;


            which is equivalent to:



            Supplier<Long> asd = () -> {
            return 1L;
            };


            However, when you write:



            Supplier<Long> asd = () -> throw new RuntimeException();


            It would be translated following which is an invalid lambda:



            Supplier<Long> asd = () -> {
            return throw new RuntimeException(); // invalid expression in Java
            };


            In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.






            share|improve this answer





















            • This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
              – Nick
              Dec 4 at 2:16















            up vote
            18
            down vote










            up vote
            18
            down vote









            What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.



            Supplier<Long> asd = () -> 1L;


            which is equivalent to:



            Supplier<Long> asd = () -> {
            return 1L;
            };


            However, when you write:



            Supplier<Long> asd = () -> throw new RuntimeException();


            It would be translated following which is an invalid lambda:



            Supplier<Long> asd = () -> {
            return throw new RuntimeException(); // invalid expression in Java
            };


            In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.






            share|improve this answer












            What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.



            Supplier<Long> asd = () -> 1L;


            which is equivalent to:



            Supplier<Long> asd = () -> {
            return 1L;
            };


            However, when you write:



            Supplier<Long> asd = () -> throw new RuntimeException();


            It would be translated following which is an invalid lambda:



            Supplier<Long> asd = () -> {
            return throw new RuntimeException(); // invalid expression in Java
            };


            In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 30 at 12:47









            Nikolas

            12.3k53263




            12.3k53263












            • This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
              – Nick
              Dec 4 at 2:16




















            • This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
              – Nick
              Dec 4 at 2:16


















            This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
            – Nick
            Dec 4 at 2:16






            This is not entirely the case, since the following program is valid: Consumer<String> consumer = str -> System.out.println(str). This is not elaborated to Consumer<String> consumer = str -> { return System.out.println(str); } (which would similarly be an invalid program). Some special rules were added to accommodate expressions of type void; it's just that these same rules weren't added to accommodate throw statements.
            – Nick
            Dec 4 at 2:16





            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?