[ 
https://issues.apache.org/jira/browse/SOLR-14579?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17188582#comment-17188582
 ] 

Uwe Schindler edited comment on SOLR-14579 at 9/1/20, 4:05 PM:
---------------------------------------------------------------

Hi,

sorry the explanation by [~noble.paul] in the code is completely wrong and the 
warnings can be resolved without some static methods! Please read the 
specification about how lambdas are working. Lambdas are NOT converted to plain 
new instances on each call (if that would be the case, tehn the whole Java 
streams API would be really damn slow). It depends on the type of lambda and 
what parameters it takes.

Before telling others here such completely wrong information, please read the 
bytecode and understand it!

For the {{k -> new HashMap()}} (the "key" is String, for demonstatrion 
purposes, see example below) there is exactly one instance of the functional 
interface created (like in your static class). It works like this:

- The lambda does not use any variable parameter from outside. This is called a 
non-capturing lambda (it captures no parameters and therefore do not need to 
bind them to the functional interface class).
- Javac creates a *static* (!!!) method in the class where the lambda is 
located:
{code:java}
private static HashMap lambda$somesuffix(String key) { return new HashMap(); }
{code}
- At the place of the lambda, javac inserts an invokedynamic to - indeed - 
create a methodHandle that generates an anonymous class. This anonymous class 
is only generated on the first call of the invokedynamic (that's the whole 
trick of invokedynamic, its called bootstrapping).
- The bootstrapper returns back a methodHandle used by the caller to receive an 
instance of the functional interface. And here it get's interesting: As you 
see, the above method is private static and the parameters passed to it are all 
coming from the lambda call, there's only exactly one instance produced. That's 
because its non-capturing. IF we would use some field/variable from the outside 
and pass it as parameter to the Hashmap constructor, only then it would create 
a new instance on each call (capturing either "this" for then created 
non-static lambda methods or a rference to the dynamic parameter).

So please fix the code and apply the patch and remove Utils.


was (Author: thetaphi):
Hi,

sorry the explanation by [~noble.paul] in the code is completely wrong and the 
warnings can be resolved without some static methods! Please read the 
specification about how lambdas are working. Lambdas are NOT converted to plain 
new instances on each call (if that would be the case, tehn the whole Java 
streams API would be really damn slow). It depends on the type of lambda and 
what parameters it takes.

Before telling others here such completely wrong information, please read the 
bytecode and understand it!

For the {{k -> new HashMap()}} (the "key" is String, for demonstatrion 
purposes, see example below) there is exactly one instance of the functional 
interface created (like in your static class). It works like this:

- The lambda does not use any variable parameter from outside. This is called a 
non-capturing lambda (it captures no parameters and therefore do not need to 
bind them to the functional interface class).
- Javac creates a static method in the class where the lambda is located:
{code:java}
private static HashMap lambda$somesuffix(String key) { return new HashMap(); }
{code}
- At the place of the lambda, javac inserts an invokedynamic to - indeed - 
create a methodHandle that generates an anonymous class. This anonymous class 
is only generated on the first call of the invokedynamic (that's the whole 
trick of invokedynamic, its called bootstrapping).
- The bootstrapper returns back a methodHandle used by the caller to receive an 
instance of the functional interface. And here it get's interesting: As you 
see, the above method is private static and the parameters passed to it are all 
coming from the lambda call, there's only exactly one instance produced. That's 
because its non-capturing. IF we would use some field/variable from the outside 
and pass it as parameter to the Hashmap constructor, only then it would create 
a new instance on each call (capturing either "this" for then created 
non-static lambda methods or a rference to the dynamic parameter).

So please fix the code and apply the patch and remove Utils.

> Comment SolrJ 'Utils' generic map functions
> -------------------------------------------
>
>                 Key: SOLR-14579
>                 URL: https://issues.apache.org/jira/browse/SOLR-14579
>             Project: Solr
>          Issue Type: Improvement
>    Affects Versions: master (9.0)
>            Reporter: Megan Carey
>            Assignee: Erick Erickson
>            Priority: Minor
>             Fix For: 8.7
>
>         Attachments: SOLR-14579.patch
>
>          Time Spent: 2.5h
>  Remaining Estimate: 0h
>
> Remove the map functions like `NEW_HASHMAP_FUN` from the Utils class in solrj 
> module to reduce warnings and improve code quality.
> [https://github.com/apache/lucene-solr/blob/master/solr/solrj/src/java/org/apache/solr/common/util/Utils.java#L92]



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org
For additional commands, e-mail: issues-h...@lucene.apache.org

Reply via email to