Finding T.class in the documentation - java

Cay Horstmann in his book Core Java describes this method for obtaining an object of type Class
If T is any Java type, then T.class is the matching class object. For
example:
Class cl1 = Date.class; // if you import java.util.*;
Class cl2 = int.class;
Class cl3 = Double[].class;
Note that a Class object
really describes a type, which may or may not be a class. For example,
int is not a class, but int.class is nevertheless an object of type
Class.
I've scanned through java.util and can't explain what is written here. That "class" seems to be a field. A field of an Object class. Though it contradicts to what is written by Mr. Horstmann who references to java.util. Could you point at where can I read about it in javadoc?

It's not in javadoc because it's not a method you call - it's part of the syntax of the language. It's a class literal, which is described in the Java Language Specification section 15.8.2:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class<C>.
The type of p.class, where p is the name of a primitive type (§4.2), is Class<B>, where B is the type of an expression of type p after boxing conversion (§5.1.7).
The type of void.class (§8.4.5) is Class<Void>.

// if you import java.util.*;
The Date class is in java.util, so you need to import it. That statement has nothing to do with class literals, which is what the syntax of TypeName.class is called.
What is a class literal in Java?
Class literals in the Java Language Specification.
A class literal is an expression consisting of the name of a class,
interface, array, or primitive type, or the pseudo-type void, followed
by a '.' and the token class.
A class literal evaluates to the Class object for the named type (or
for void) as defined by the defining class loader (§12.2) of the class
of the current instance.

Related

Where is .class defined in Java? (Is it a variable or what?)

There are 2 ways to get a class's Class object.
Statically:
Class cls = Object.class;
From an instance:
Object ob = new Object();
Class cls = ob.getClass();
Now my question is getClass() is a method present in the Object class,
but what is .class? Is it a variable? If so then where is it defined in Java?
That's implemented internally and called a class literal which is handled by the JVM.
The Java Language Specification specifically mentions the term "token" for it.
So .class is more than a variable, to be frank it is not a variable at all. At a broader level you can consider it as a keyword or token.
https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.8.2
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
A class literal evaluates to the Class object for the named type (or for void) as defined by the defining class loader (§12.2) of the class of the current instance.
That information resides in the class 'file', although classes need not have a physical .class file in the file system. The JVM takes care of making it available from the class definition, as the other answer states.
See also:
https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html

Java Reflect API - isAssignableFrom, Extends/Implements

In Java Reflect API, in .isAssignableFrom methods in Class has its javadocs saying that it will return true if "the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter".
The question is whether .isAssignableFrom will return true if on a class that implements Interface, or it only returns true when "extends" is used?
In other words, what will happen and why in case:
public class MyClass implements MyInterface{}
MyInterface.isAssignable(MyClass.class) == false/true ?
It returns true.
That are two ways to tell this from the Javadoc:
the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter
The term superinterface is defined in the Java Language Specification as follows:
The optional implements clause in a class declaration lists the names of interfaces that are direct superinterfaces of the class being declared.
Therefore, MyInterface is a superinterface of MyClass, and therefore MyInterface.class.isAssignableFrom(MyClass.class) is true.
The other way to tell is the next paragraph of the javadoc:
Specifically, this method tests whether the type represented by the
specified Class parameter can be converted to the type
represented by this Class object via an identity conversion
or via a widening reference conversion. See The Java Language
Specification, sections 5.1.1 and 5.1.4 , for details.
which matches because
MyInterface i = new MyClass();
compiles.

Where is ObjectClass.class variable defined/initialized?

Consider sample code below
public class Test {
public static void main(String args[]) {
Test t = new Test();
Class c2 = Test.class;
System.out.println(c2);
}
}
Test.class statically evaluates and returns compile time Class object. Looking at the Test.class syntax it looks like the variable class is of type java.lang.Class and is static and public. My question is where is this variable defined? It is not present in Test class (because I don't declare it) neither it is in the java.lang.Object class.
I saw an analogous method public final native Class<?> getClass();. This is present in java.lang.Object and is a native java method. This method returns the runtime Class of an object.
So my question is where is this public & static class variable defined?(Please correct me if I have mistaken) Is it again some native implementation? This is set at compile time and being static needs no class instance to be created. So if even this is some native implementation is it initialized by registerNatives() method in java.lang.Object?
These are called class literals and are defined by the language itself as per JLS §15.8.2 (there is no "class member"):
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class<C>.
The type of p.class, where p is the name of a primitive type (§4.2), is Class<B>, where B is the type of an expression of type p after boxing conversion (§5.1.7).
The type of void.class (§8.4.5) is Class<Void>.
One indication that these constructs are intrinsically built into the language is that they even work with primitives!
System.out.println(int.class);
System.out.println(double.class);
// etc.
class is not normal static variable. It's a language construct which is replaced at compilation time.
Because class is a keyword it wouldn't even be possible to declare a variable with that name.
Your assumption that class is a static field of class Class is not exact. Assume that this is correct. In this case the value of this field will be exactly the same for all classes that is wrong.
Although MyClass.class syntactically looks like access to static field it is just a special syntax of language. Think about this as a kind of operator.
Probably JVM creates some kind of synthetic class that wraps real class and has such field but it is just an assumption about internal representation of classes in JVM.

A method for obtaining an object of type Class

In my textbook I can read:
If T is any Java type, then T.class is the matching class object. For example:
Class cl1 = Date.class; // if you import java.util.*;
Class cl2 = int.class;
Class cl3 = Double[].class;
Later on I'm reading:
The virtual machine manages a unique Class object for each type. Therefore, you can use the == operator to compare class objects. For example:
if (e.getClass() == Employee.class)
Could you help me find anything about this .class field in the documentation.
And another qutstion - I can't understand whether the e.getClass() == Employee.class is the same as e.class == Employee.class. I mean, if it is the same, why the author of the textbook used getClass here in the lefthand expression.
From JLS §15.8.2 - Class Literals:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.
The type of C.class, where C is the name of a class, interface, or array type (§4.3), is Class.
So, Date.class, int.class are nothing but class literals, which give appropriate Class objects for a class type.
I can't understand whether the e.getClass() == Employee.class is the same as e.class == Employee.class
No, they are not the same. In fact, e.class won't even compile. As per the definition of class literal above, since e is not a type but an object of Employee (I assume that), e.class is not a valid class literal. To get the Class object of a class, using it's instance, you need to use Object#getClass() method.
So, e.getClass() and Employee.class are two different ways to obtain the Class object for Employee class. Both to be used in different circumstances. When you know the class type, use 2nd version, and when you have an instance of your class, use the 1st version.
However, note that in case of inheritance, e.getClass() might not return the same Class object as Employee.class. The former would return the Class object of the actual subclass object, referred by the reference e, whereas the later would always give you Class<Employee>.
If you neither have the instance, nor the class type available, then you can also get the Class object for a class name in String form, using - Class#forName(String) method.
How you get a Class object depends on what you already know. If you have an object referenced by x, you can obtain the Class object for its class by x.getClass(). If you know, when you are writing your code, the name of a type T, you can use T.class to get the class object. There is a third approach, less convenient, that only requires run time access to the class name.
The getClass method is described as one of the Object methods, in the Object API documentation.
Class literals, the T.class form, are described in the Java Language Specification.
The third approach uses one of the static forName methods defined the API documentation for java.lang.Class.

About the "class" property/field

When you do:
MyClass.class.someMethod()
What exactly is the "class" field? I can't find it in the API docs. Is it an inherited static field?
I thought reserved keywords were not allowed as entity names.
Please read :
A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a `.' and the token class. The type of a class literal, C.Class, where C is the name of a class, interface or array type, is Class. If p is the name of a primitive type, let B be the type of an expression of type p after boxing conversion (§5.1.7). Then the type of p.class is Class. The type of void.class is Class.
Java Language Specification: 15.8.2. Class Literals
The .class is not actually a field. You can think of is as more of an 'extension' like a file extension. It is a token used to differentiate the Class Object as opposed to an instance of the class.
MyClass is not the name of an object, it's a class name, so this is actually special syntax that retrieves the corresponding Class<MyClass> object for the named class. It is a language feature, not a real property of the MyClass class.
This is documented here:
http://java.sun.com/javase/6/docs/api/java/lang/Class.html

Categories

Resources