Some Classes with a public void close() don't implement AutoCloseable

forax at univ-mlv.fr forax at univ-mlv.fr
Sun Apr 19 16:55:49 UTC 2020


----- Mail original -----
> De: "Johannes Kuhn" <info at j-kuhn.de>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "discuss" <discuss at openjdk.java.net>
> Envoyé: Samedi 18 Avril 2020 22:49:07
> Objet: Re: Some Classes with a public void close() don't implement AutoCloseable

> On 17-Apr-20 1:00, forax at univ-mlv.fr wrote:
>> A couple of points,
>> - it can be fixed by making TWR using a functional type instead of a nominal one
>>    by supporting a syntax like try(expr) { }. But this is in the same realm of
>>    ideas as allowing the enhanced for loop to use a an Iterator::iterator, so it
>>    has been rule out has a step too far by the lambda EG.
>> - until lambdas are retrofitted as inline types, i'm worry people will use
>> forceTryable with a ReentrantLock,
>>     try(var __ = forceTryable(lock::unlock)) { ... }
>>    because most of the time, the lambda will not be allocated but not always,
>>    sometimes it may still be found escaping by the JITs.
>> - my preferred fix is, as you already, know to remove the concept of checked
>> exceptions from the language instead of spending time running in circles around
>> them.
>>
>> Rémi
> 

Hi Johannes,

> While this can not be implemented outside of ReenetrantLock,
> ReenetrantLock could do it:
> 
> private final AutoCloseable unlocker = this::unlock;
> public AutoCloseable autoLock() {
>     this.lock();
>    return unlocker;
> }
> 
> The type should be narrowed down so it doesn't declare to throw
> Exception, but you get the idea.

yes, this solution has the advantage that if a lock is constructed then this::unlock has been correctly allocated,
but it means that even if the application don't use autoLock, you pay an allocation per lock.
You can fix that issue with the code below

  public AutoCloseable autoLock() {
    AutoCloseable unlocker = this::unlock;   // allocation before taking the lock !
    this.lock();
    return unlocker;
  }

> 
> Also, I don't quite understand how inline types would get rid of the
> allocation.
> The type declared in the class file (with the TWR) is the interface, so
> the inline type might need to be widened.
> From my understanding, if and when the widening happens is subject to
> the JIT.
> The benefit (again, to my understanding) is that widened inline values
> are indistinguishable from other widened inline values with the same
> contents,
> so the JIT can defer the widening as much to it's liking. Or not. And
> the widening includes an allocation & copy of the data from stack to heap.
> Or did I miss something obvious? (And how does the interpreter deal with
> all that?)

yes, it depends if the code is JITed or not. If the code is JITed, given that the lambda creation and the last usage (the call to close()) are in the same method, if nobody is stupidly using the lambda inside the TWR body (that why i have used __ as identifier), any JITs will use the lambda real type and not the interface, so no allocation !

> 
> Johannes

Rémi

> 
>> ----- Mail original -----
>>> De: "John Rose" <john.r.rose at oracle.com>
>>> À: "Remi Forax" <forax at univ-mlv.fr>
>>> Cc: "Johannes Kuhn" <info at j-kuhn.de>, "discuss" <discuss at openjdk.java.net>
>>> Envoyé: Jeudi 16 Avril 2020 23:31:49
>>> Objet: Re: Some Classes with a public void close() don't implement AutoCloseable
>>> Nice.  I tried to find a way to make this a little more generic
>>> and came up with an API which handles arbitrary exceptions
>>> and is packaged as a method instead of a special idiom.
>>> There’s a natural-enough method called `forceTryable` that
>>> could be created.
>>>
>>> http://cr.openjdk.java.net/~jrose/jdk/ForceTryableDemo.java
>>> https://bugs.openjdk.java.net/browse/JDK-8243015
>>>
>>> (There are further generalizations of this, if you look at it as
>>> a “named cast method” for a functional interface type related
>>> to AutoCloseable.  See my comment on JDK-8243015.)
>>>
>>> — John
>>>
>>> On Apr 15, 2020, at 8:53 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>>>> interface FakeAutoCloseable extends AutoCloseable { public void close(); }  //
>>>> suppress exception
>>>>
>>>> XMLReader xmlReader = ...
>>>> try(FakeAutoCloseable __ = xmlReader::close) {
> >>>   …


More information about the discuss mailing list