On Wed, Nov 3, 2021 at 6:35 PM John Rose <john.r.r...@oracle.com> wrote:
Let’s see what happens if we say that (a) bare values have headers > and (b) Object::getClass allows the user to observe part of the header > contents. > I'm asking specific questions below as best I can, but I must confess that I don't really follow what this thought experiment is trying to demonstrate overall. It follows then that the expression aPointVal.getClass() will show the > contents of aPointVal’s header, even if it is a compile-time constant. > > Point pv = new Point(42,42); // “class Point” is the definition of Point > assert pv.getClass() == Point.class; // ok, that’s certainly the class > (Header or not, that could just be a hardcoded synthetic method anyway? Have I been missing something big when I keep pointing out that this method would be patently useless? When static type is MyValueClass, result is MyValueClass.class, always, no?) > assert pv.getClass() != Point.ref.class; // and it’s not a ref, so good > > That is all fine. There’s a little hiccup when you “box” the point and > get the same Class mirror even though the “header” is a very real-heap > resident value now: > > Point.ref pr = pv; // same object… now it’s on the heap, though, with a > real live heap header > assert pr.getClass() == Point.class; // same class, but... > Why would we even want this? It would be very surprising/puzzling to me. > assert pr.getClass() != Point.ref.class; // we suppress any distinction > the heap header might provide > > There’s a bigger hiccup when you compare all that with good old int: > > int iv = 42; // “class int” is NOT a thing, but “class Integer” is > assert iv.getClass() != int.class; // because int is not a class > No matter: array types aren't classes either. (If they're treated as such internally, hats off to you folks, because that bit of trivia basically never leaks, except perhaps for the particular misnamed-in-retrospect method/type/literal trio we're talking about here. And that's great. Either way, array types aren't classes, and `getClass` means "get runtime type" (for a reasonable definition thereof), and ergo, I'd guess that assertion and the next below to fail.) assert iv.getClass() == Integer.class; // ah, there’s the class! > assert iv.getClass() == int.ref.class; // this works differently from Point > assert ((Object)iv).getClass() == pr.getClass(); // this should be true > also, right? > Not sure what that's meant to return, but surely casting to Object must do nothing different from casting to Integer or int.ref. > And to finish out the combinations: > > int.ref ir = iv; // same object… now it’s on the heap, though, with a > real live heap header > assert ir.getClass() == Integer.class; // same class > assert ir.getClass() == int.ref.class; // and this time it’s a ref-class > (only for classic primitives) > assert ir.getClass() != int.class; > > All this has some odd irregularities when you compare what Point does and > what int does. And yet it’s probably the least-bad thing we can do. > > A bad response would be to follow the bad precedent of ir.getClass() == > Integer.class off the cliff, and have pv.getClass() and pr.getClass() > return Point.ref.class. That way, getClass() only returns a ref. Get it, > see, getClass() can only return reference types. The rejoinder (which > Brian made to me when I aired it) is devastating: Point.class is the > class, not Point.ref.class, and the method is named “get-class”. > If s/named/misnamed/ is it still devastating? :-) With this my brain has given its last feeble gasp of the night. -- Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com