Static fields in specialized classes

Paul Benedict pbenedict at apache.org
Wed Oct 15 13:48:23 UTC 2014


I throw my lot in with Ben and Stephen. I don't think specialization should
be exposed to the point that you can tell the difference with .class.
That's very disruptive to code and surprising. Rather, I think you should
expose more methods on Class to query the specialization type -- that was
something I recommended in the beginning and still favor.


Cheers,
Paul

On Wed, Oct 15, 2014 at 3:30 AM, Ben Lewis <benlewisj at gmail.com> wrote:

>  I think having Foo.class and Foo<int>.class be different is a mistake.
>
> class Person{}
>
> class Employee<any T> extends Bar{
>      //lots of other stuff irrelevant to T
>      T getId(){ … }
> }
>
> Person p1=new Employee<Object>();
> Person p2=new Employee<int>();
>
> As I understand it
>
> p1.class==Employee.class;//true
> p2.class==Employee.class;//false
> p1 instanceof Employee;//true
> p2 instanceof Employee;//false
>
> How to determine b2 comes from ‘source class’ Employee?
>
> This will cause bugs in situations where the programmer expects how the
> class hierarchy acts now rather than changing it to where specialisation
> having a different class. This would also mean migrating <T> to <any T>
> will cause backward compatibility issues.
>
> For example
>
> if(p instanceof Employee){
>    //do something
> }else{
>    //do something else
> }
>
> if written before specialisations It would do as expected but after and if
> p=new Employee<int>() it would execute the else block not as expected when
> the code is written.
>
> On Wed, Oct 15, 2014 at 12:59 PM, Brian Goetz <brian.goetz at oracle.com>
> wrote:
>
> > My gut feeling is that this is undesirable and should be disallowed,
> >> and that perhaps we shouldn't even be able to observe Foo<int>.class
> >> at all.
> >>
> >
> > If you think about the problem a little more, I think you'll find that
> > this is wishful thinking.  (But of course, you're free to have a gut
> > feeling without having thought about it at all.)
> >
> >  After all, if specialization is intended to be viewed primarily as an
> >> implementation detail
> >>
> >
> > It is an implementation detail in the same sense that erasure is; that
> > generics are implemented by erasure almost certainly leaks into the
> user's
> > perception too.  (Erasure is why you can't have Foo<String>.class, for
> > example.  Among many other things that the user has to pay attention to.)
> >
> > class Foo<any T> {
> >     T get() { ... }
> > }
> >
> > Consider the members of various instantiations of Foo.
> >
> > The signature of get() in Foo<String> is "String get()", but the
> signature
> > of get() in Foo<int> is "int get()".  The erasure of the first is "Object
> > get()"; the erasure of the second is "int get()".  While all erased
> > reference instantiations can be implemented by the same class, the
> > primitive/value instantiations cannot be.
> >
> > Similarly, Foo<int> can't extend Foo<?> (because that really means Foo<?
> > extends Object>, and has to for compatibility reasons), nor can it extend
> > raw Foo.  (Which is fine; raw types exist solely to support migration
> from
> > ungenerified codebases to generified ones.)
> >
> > We could hide the existence of List<int>.class, but that would just make
> > life harder for users, who would then have to jump through bigger hoops
> to
> > reflect over the members of List<int> (which are different from the
> members
> > of List<String>, even after erasure.)
> >
> >  In other words, while the Java language/library changes may be
> >> expressed by some improvements to reflection, I'd be concerned about
> >> the many implemented algorithms based on reflection.
> >>
> >
> > It is of course reasonable to be concerned.  Stay tuned and see if your
> > concerns are addressed.
> >
>


More information about the valhalla-dev mailing list