Throwing exceptions from records

Remi Forax forax at univ-mlv.fr
Thu Mar 5 20:50:21 UTC 2020


----- 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.

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 :)

regards,
Rémi


More information about the amber-dev mailing list