I once did this in a class project, including even manually creating the bytecode at runtime. Ironically, it's probably the most understandable and maintainable of the crazy metaclass-style reflection I've done (although that's probably mostly due to the fact that the scope was much more limited: I was only mirroring a set of interfaces into a different namespace to work around some stupid limitation in a different library).
> People coming from Javaville or C#land definitely don't have that kind of abstraction
What do you mean? A class is an object in both Java and C#.
What you see as the Class type in Java, at least, is simply a representation of a class. It can tell you about a class, but it doesn't represent an actual thing you can manipulate, change, or use. I can't add a method to that class, or add a field, or manipulate its instances beyond basic method lookup and dispatch.
In something like Ruby or Smalltalk, a Class is an object. It can be changed live, altered, adapted, cloned, or otherwise used just like another object; and the application will change its behavior accordingly, right there on the spot.
I'd recommend reading up on prototype inheritance, as that is the model generally used in the latter languages.
> I'd recommend reading up on prototype inheritance
Thanks but I’ve already literally got my PhD in metaprogramming in Ruby and object model implementation in Java. Ruby doesn’t use anything like prototype inheritance.
That said, maybe the difference here is how often the janky metaprogramming of classes interferes with day to day peogramming; a java programmer might have never seen this stuff, moreso then a ruby one?
That said, there is a qualitative difference in what we call 'classes' in those two environments, which is part of why I think there's confusion. Class in Java is a fairly different concept than a Class in Smalltalk, Ruby, or JS.
Class foo = String;
in Java? If so I guess classes really are objects, if not I'd say "there are some objects that represent (or wrap) some classes somehow."That’s completely orthogonal to whether they’re objects or not.
You can keep fiction and non-fiction in separate bookshelves if you want but when you get either off the shelf it’s still a book.
In languages I'm used to, an object is a type of value, and values are things that you can store in (or refer to with) variables.
The only vaguely object-like feature of Java classes I can think of is that you can look up (static) methods/attributes on them with a dot.
Or is there more? You can't call `String.toString()`, so `String` isn't an instance of something that inherits from `Object`. I'm at a bit of a loss here... There obviously exist "class objects", but they're not normally what people refer to when they talk about classes. I'd say Java classes are almost purely lexical constructs (though I could be wrong there -- again, I don't know much about Java...)
Class theStringClass = String.class;
Class[] myArrayOfClasses = new Class[1];
myArrayOfClasses[0] = theStringClass;
callSomeOtherMethod(theStringClass);
> You can't call `String.toString()`
String.class.toString() => "class java.lang.String"
theStringClass.toString() => "class java.lang.String"
myArrayOfClasses[0].toString() => "class java.lang.String"
somethingThatReturnsAClass().toString() => "class java.lang.String"
> `String` isn't an instance of something that inherits from `Object`
Class theObjectClass = Object.class;
theObjectClass.isAssignableFrom(theStringClass) => true
> I'd say Java classes are almost purely lexical constructs
They aren't - here's the source code for the Class class.
https://github.com/Project-Skara/jdk/blob/c2105ced865fba11fb...
Here's the source code for the toString method we were calling
https://github.com/Project-Skara/jdk/blob/c2105ced865fba11fb...
Class foo = String.class;
(Though `Class` is actually a generic type, so you'd want to include the type parameter in actual code.)Hah, I think "an object that is the String class" begs the question :-). I think that `String.class` is an object because you can do objecty things with it (call methods, assign it to a variable etc) and `String` is not an object because you can't do any of those things with it.
To me they're not the same kind of thing, though they're intimately, inseparably and exclusively related. I personally would say even if
new String()
was just syntactic sugar for String.class.newInstance()
, and all other "bare" uses of `String` were similarly shorthands for operations on `String.class`, I'd still hesitate to say that `String` itself was an object.My logic is probably less useful than yours, though. I'd say "`A` is a `class`, but `a` is an instance of `Class`" and in your system where `A` and `a` are "the same thing" there's no difference between being a `class` and being an instance of `Class`. Because the things appear in different namespaces (as you say), and are related one-to-one, we could as well say they are two ways to refer to "the same thing", with different operations possible "depending on the phrasing."
Shrugs, it doesn't come naturally to me, but it's at least a self-consistent system.
>>> str("foo")
'foo'
>>> x = str
>>> x("foo")
'foo'
and the "builtin" str and "userspace" x are equally first-class. new String("foo");
in Java, how do I get an object that can take the place of String in that expression? String.class has some relationship with the "String" in the code I quoted, but it's not the same thing; the thing that I apply new to is not a thing I can call methods on, and the thing that I can call methods on is not a thing I can apply new to.