Throwing exceptions from records

Ty Young youngty1997 at gmail.com
Sat Mar 7 14:41:08 UTC 2020


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


>
> 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. 
Anything more than the basic "Point" example is too much for the current 
record implementation, it seems.


>
> regards,
> Rémi


More information about the amber-dev mailing list