Let\'s say I have:
class A {
Integer b;
void c() {}
}
Why does Java have this syntax: A.class
, and doesn\'t have a syntax
The A.class
syntax looks like a field access, but in fact it is a result of a special syntax rule in a context where normal field access is simply not allowed; i.e. where A
is a class name.
Here is what the grammar in the JLS says:
Primary:
ParExpression
NonWildcardTypeArguments (
ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
Identifier { . Identifier }[ IdentifierSuffix]
BasicType {[]} .class
void.class
Note that there is no equivalent syntax for field
or method
.
(Aside: The grammar allows b.field
, but the JLS states that b.field
means the contents of a field named "field" ... and it is a compilation error if no such field exists. Ditto for c.method
, with the addition that a field c
must exist. So neither of these constructs mean what you want them to mean ... )
Why does this limitation exist? Well, I guess because the Java language designers did not see the need to clutter up the language syntax / semantics to support convenient access to the Field and Method objects. (See * below for some of the problems of changing Java to allow what you want.)
Java reflection is not designed to be easy to use. In Java, it is best practice use static typing where possible. It is more efficient, and less fragile. Limit your use of reflection to the few cases where static typing simply won't work.
This may irk you if you are used to programming to a language where everything is dynamic. But you are better off not fighting it.
Is there any use that is so common for class literals?
I guess, the main reason they supported this for classes is that it avoids programs calling Class.forName("some horrible string")
each time you need to do something reflectively. You could call it a compromise / small concession to usability for reflection.
I guess the other reason is that the
syntax didn't break anything, because class
was already a keyword. (IIRC, the syntax was added in Java 1.1.)
* If the language designers tried to retrofit support for this kind of thing there would be all sorts of problems:
method
and field
were turned into keywords.b.field
as an implicit object attribute, because it doesn't apply to objects. Rather b.field
would need to apply to field / attribute identifiers. But unless we make field
a reserved word, we have the anomalous situation that you can create a field called field
but you cannot refer to it in Java sourcecode.c.method
, there is the problem that there can be multiple visible methods called c
. A second issue that if there is a field called c
and a method called c
, then c.method
could be a reference to an field called method
on the object referred to by the c
field.