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

            How to change which sound is reproduced for terminal bell?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

            Can I use Tabulator js library in my java Spring + Thymeleaf project?