Consider the simplest possible example. We have
public class Foo {}
Therefore we can say
Foo.class // ==> class Foo
It therefore stands to reason that Foo
should be a java.lang.Class
, as we clearly have access to it and can manipulate it in the current context. Yet
Foo instanceof java.lang.Class
raises the error
cannot find symbol
symbol: variable Foo
Foo instanceof java.lang.Class
^-^
This isn't anything to do with instanceof itself, though; just
Foo
alone in the OpenJDK shell produces the same error.
How can we be accessing properties on Foo
if Foo
does not exist in the current context?
A class name may be used in your source code as a part of many different expressions. It doesn't mean that the class name itself is an object; it just means that the name itself can be used as part of a bigger expression. These are not "properties" or attributes; they are other syntactical constructions used to form expressions with many different parts.
The JLS defines how a "TypeName", e.g. Foo
can be used to form expressions in Chapter 15. Specifically:
Section 15.8.2, Class Literals.
TypeName {[ ]} .
class
Section 15.8.4, Qualified this, to access the lexically enclosing class.
TypeName .
this
Section 15.11, Field Access Expressions, to access the lexically enclosing class as a superclass.
TypeName .
super
. IdentifierSection 15.12, Method Invocation Expressions, to call a static method.
TypeName . [TypeArguments] Identifier ( [ArgumentList] )
TypeName .
super
. [TypeArguments] Identifier ( [ArgumentList] )Section 15.13, Method Reference Expressions, to refer to methods of an enclosing class that may be invoked later.
TypeName .
super
:: [TypeArguments] Identifier
It may also be a "Reference Type" eligible for other expressions, such as:
Section 15.16, Cast Expressions, to create cast expressions.
( ReferenceType {AdditionalBound} ) UnaryExpressionNotPlusMinus
Section 15.20.2, Type Comparison Operator
instanceof
, usinginstanceof
.RelationalExpression
instanceof
ReferenceType
There are specific uses of a type name e.g. Foo
that are described above. This does not imply that the type name can be used generally as its own object. Type names are allowed only as part of larger expressions that can be otherwise unrelated.