Throwing exceptions from records

Ty Young youngty1997 at gmail.com
Sun Mar 8 00:51:48 UTC 2020


On 3/7/20 10:05 AM, Remi Forax wrote:
> ----- Mail original -----
>> De: "Ty Young" <youngty1997 at gmail.com>
>> À: "amber-dev" <amber-dev at openjdk.java.net>
>> Envoyé: Samedi 7 Mars 2020 15:41:08
>> Objet: Re: Throwing exceptions from records
>> On 3/5/20 2:50 PM, Remi Forax wrote:
>>> ----- Mail original -----
>>>> De: "Ty Young" <youngty1997 at gmail.com>
>>>> À: "amber-dev" <amber-dev at openjdk.java.net>
>>>> Envoyé: Jeudi 5 Mars 2020 21:04:40
>>>> Objet: Re: Throwing exceptions from records
>>>> On 3/5/20 1:39 PM, Vicente Romero wrote:
>>>>> Hi Ty,
>>>>>
>>>>> On 3/5/20 2:12 PM, Ty Young wrote:
>>>>>> Actually going to expand this a bit after messing around with records...
>>>>>>
>>>>>>
>>>>>> How is records supposed to work beyond the most basic usage of
>>>>>> Point(int x, int y)? There isn't much information out there for the
>>>>>> more advanced usages so I'm confused.
>>>>>>
>>>>>>
>>>>>> To go into more detail, I'm trying to convert this:
>>>>>>
>>>>>>
>>>>>> https://github.com/BlueGoliath/Goliath-Nvidia-Bindings/blob/master/modules/org.goliath.bindings.nvml/src/main/java/org/goliath/bindings/nvml/functions/nvmlInit.java
>>>>>>
>>>>>>
>>>>>>
>>>>>> which doesn't seem possible as-is because you can't throw exceptions
>>>>>> from record constructors.
>>>>> you can't throw exceptions from _canonical_ record constructors, being
>>>>> a canonical record constructor the one with the same signature as the
>>>>> record header but you can do:
>>>>>
>>>>> record R(int i) {
>>>>>       public R() throws Exception {  // not a canonical constructor so
>>>>> no restriction
>>>>>           this(someMethodReturningIntThatThrows());  // invoking the
>>>>> canonical constructor
>>>>>       }
>>>>> }
>>>>>> Furthermore there seems to be some constraint where constructor
>>>>>> arguments have to match the record argument signature. Why does that
>>>>>> even matter?
>>>>> only the canonical but you can declare other constructors with a
>>>>> different signature
>>>> The problem is that the constructor arguments require preprocessing but
>>>> you can't do that since the canonical constructor has to be called
>>>> first. I suppose static methods could be used to do that but that feels
>>>> like a bad workaround for something that will probably be fairly common.
>>> It's common to avoid to throw checked exceptions in constructor because instead
>>> of first creating the object (with new) and then throwing the exception, it's
>>> better to throw the exception before the creation of the object. The usual
>>> alternatives are as you said either use a static method which is very common
>>> when dealing with IOException or use an unchecked exception instead.
>>
>> Not really my choice. I've asked JDK developers to add an alternative
>> method that doesn't throw the exception and have been ignored multiple
>> times now. I'm not even the only one who has asked for an alternative
>> either.
>>
>>
>> Seems to be a fairly common response(or lack thereof)...
> in this specific case, why not catching NoSuchMethodException and re-throw a NoSuchMethodError ?


What do you mean? If you try-catch something then it'd be non-final.


>
>>
>>> and as a meta comment, debugging constructors is hard because you are at the
>>> point where every objects is mutable, it's a good idea to only have
>>> initialization code in a constructor (this.foo = foo) or preconditions
>>> (Objects.reuireNonNull(...)), so to have a code is so simple that you will
>>> never have a bug in a constructor. If you follow that rule, i promise you will
>>> never be angry anymore :)
>>
>> Not really relevant. Records shouldn't prevent people from doing basic
>> in-constructor processing. The current record implementation is foobar.
> I respectfully disagree. Records doesn't have to support all scenarii supported by classes, otherwise you will end up with records being classes.


I didn't say it did?


> A record is a data carrier, with the data being created before and stuff into the data carrier, so there is no need to support a constructor with checked exceptions.


Who said the data had to be constructed before the record? I've watched 
dozens of presentations on Records via JDK developers and not once was 
this ever said.


The only two things that make something a record is if:


A. it can be reconstructed repeatably given the same arguments(somewhat 
like a pure function).


and


B. all instance fields are always final.


Never mind the issues with A(it can't be enforced), none of that says 
anything about how record fields are set. It sure as heck never says 
that the first statement of non canonical constructors must call the 
canonical constructor first, nor does it specify whether or not 
exceptions can or should be throwable.



>
>> Anything more than the basic "Point" example is too much for the current
>> record implementation, it seems.
> I would love this to be true, codes using records will be so easy to read and understand.


Right, because any and all meaningful logic is just thrown in other 
places making them more complicated.


>
> regards,
> Rémi


More information about the amber-dev mailing list