It seems to me you have to do a lot of hacky stuff to get around the "ugly"
API as you call it.
Maybe it'd be better to separate out the ObjectSupport class into two
separate classes, a HasherSupport class and an EqualsSupport class.
interface HashSupport<T> {
public static <T> HashSupport<T> of(Lookup lookup, String... fields) {
var mh = createMh(lookup, fields);
return (obj) -> {
mh.invokeExact(obj);
};
}
int hashCode(T obj);
}
and similar for EqualsSupport.
I feel like ObjectSupport is a bit nebulous and open ended and you'd
inevitably end up needing more support methods such as a toString method.
On Friday, April 26, 2019 at 8:13:17 AM UTC-7, Remi Forax wrote:
>
>
>
> ------------------------------
>
> *De: *"Steven Stewart-Gallus" <[email protected] <javascript:>>
> *À: *"mechanical-sympathy" <[email protected] <javascript:>>
> *Envoyé: *Vendredi 26 Avril 2019 01:51:47
> *Objet: *Re: Exotic classes
>
>
> Hi Steven,
> thanks for spending some time on this,
>
>
> 1. Why
> publicabstractclassObjectSupport{
> publicabstractboolean equals(Objectself,Object other);
> publicabstractint hashCode();
> publicstaticObjectSupport of(Lookup lookup,String... fields){
> // impl details
> }
> // impl details
> }
>
> and not something like?
> interfaceObjectSupport<T>{
> publicboolean equals(T self, T other);
> publicint hashCode(T obj);
> publicstatic<T, U extendsObjectSupport<T>>T of(Lookup lookup,Class<U>
> iface,Class<T> obj){
> // impl details
> }
> }
> @Retention(RetentionPolicy.RUNTIME)
> @Target(ElementType.FIELD)
> @interfaceObjectSupportField{
> }
>
>
> There are three questions, why not use an interface, why not use generics
> to make the API more typesafe and why not use an annotation to mark the
> fields,
> (1), it should be an interface, yes :
> (2), yes, the API can be more typesafe, i've implemented that. BTW, the
> correct type of equals() if generified is (T, Object), because you can call
> equals(Person, String), it should return false.
> (3),the API you propose can be built on top of the existing one, that's
> why there is an overload of ObjectSupport.of() that takes a function as
> third parameter
> see
> https://github.com/forax/exotic/blob/master/src/test/java/com.github.forax.exotic/com/github/forax/exotic/ObjectSupportTests.java#L310
>
> so i've updated the code according to (1) and (2).
>
> 2. I don't understand why you can't use
> https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.Lookup.html#defineClass-byte:A-
> instead
> of unsafe. If you can use
> https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html
> things
> might be easier to optimise because the VM doesn't trust nonstatic final
> fields but I don't think you'll need to rely on that.
>
>
> I need a VM anonymous class otherwise the method handles used to implement
> equals and hashCode are not considered as constant by the JIT. A previous
> version of the API was using one lambdas for equals and one for hashCode,
> but it makes the API ugly. see
> https://github.com/forax/exotic/commit/168736c43f32520ef6e280db174bf8a848ee4421#diff-0b01bd4ba5740e6b300bfa38e337dd71R13
>
> 3. The raw class file isn't always available at runtime so you can't
> necessarily use ObjectSupportImpl as a template.
>
>
> yes, i will inline it (storing it as an array of bytes inside the Java
> code) once the API is stable enough.
>
> 4.
> https://github.com/forax/exotic/blob/master/src/main/java/com.github.forax.exotic/com/github/forax/exotic/ObjectSupport.java#L180
> Pretty
> sure you want a static final field here. You can do that if you're using
> ObjectSupportImpl as a raw template. Unfortunately defineClass doesn't
> accept arguments so you have to use wonky garbage like a hashmap to pass
> runtime data that can't be embedded in a class file easily.
>
>
> No need for static fields there because ObjectSupportImpl is loaded as a
> VM anonymous class, so the instance fields are considered as constant if
> the object itself is a constant (see the answer to your question 2).
>
> There is a JMH test if you want to take a look to the generated assembly
> code
>
> https://github.com/forax/exotic/blob/master/src/test/java/com.github.forax.exotic/com/github/forax/exotic/perf/ObjectSupportBenchMark.java
>
> regards,
> Rémi
>
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected] <javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
>
--
You received this message because you are subscribed to the Google Groups
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.