Hacker News new | ask | show | jobs
by jonathankoren 2790 days ago
Java has Class which is an Object.
1 comments

Honest question: Can you write

    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."
I think what you mean is that classes are referenced by a separate namespace in Java and aren’t in Ruby.

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.

I guess I'm not sure what "object" means in Java, then.

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

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

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.)
Sure, I'd say that fits my second suggested wording -- `String.class` is an object that represents or wraps the `String` class.
How do you tell the difference between an object that is the String class, and an object that represents the String class? If you can call .toString on it, and you can compare it to other classes, and you can call .newInstance, then how is it more of a representation than being the actual thing?
> How do you tell the difference between an object that is the String class, and an object that represents the String class?

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.

In java you have to call the special and awkward .newInstance rather than being able to use standard "new". Whereas in e.g. Python I can equally well do

    >>> str("foo")
    'foo'
    >>> x = str
    >>> x("foo")
    'foo'
and the "builtin" str and "userspace" x are equally first-class.
Sure, the ergonomics are different. One is a statically compiled language and one is dynamic. But it's still an object.