15

Here is what JavaDoc says:

public final Class <?> getClass()

Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class.
The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:

Number n = 0;
Class<? extends Number> c = n.getClass();

Returns:
The Class object that represents the runtime class of this object.

Now , I understand it is a native method , so it is is implemented in platform-dependent code. But what about the return type of this method.

public final Class<?> getClass()

Also , consider the code:

class Dog
{
    @Override
    public String toString()
    {
        return "cat";
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Dog d= new Dog();
        //Class<Dog> dd = new Dog();  Compile time error
        System.out.println(d.getClass());
    }
}

Output:

class Dog

So, my query lies in :

  1. Return type of this method
  2. toString method is not called . A similar post on this topic is : Java. getClass() returns a class, how come I can get a string too?
  3. The commented code which otherwise give compile time error.
Community
  • 1
  • 1
Number945
  • 4,631
  • 8
  • 45
  • 83
  • In java, a `Class` is an actual valid `Object` type. Maybe look into the java docs on `Class`. The commented code gives an error because `Class` should be set to a `Class` object, while `new Dog()` returns a `Dog` object. – CollinD Oct 03 '15 at 05:06
  • 1
    It's not a native method. As the docs say, an object of type `Class` merely *represents* a class. Every `Object` has a reference to the `Class` representing its class, and `getClass()` is just an ordinary getter for it. – Kevin Krumwiede Oct 03 '15 at 07:08
  • @KevinKrumwiede , have a look here :http://stackoverflow.com/questions/26626259/how-does-the-getclass-is-implemented-in-java Now i m confused if it is native or not ? – Number945 Oct 03 '15 at 09:35
  • 1
    This is the source code from java.lang.Object's class definition: `public final native Class> getClass();`. As the representation of an object is a matter of the implementation, code accessing this implementation-defined data structure would better be "native". There has to be a limit between what doesn't have to be native and what must be native. (See also: Barber's Paradox) – laune Oct 03 '15 at 09:57

3 Answers3

9

The data for each object contains a reference to an object of class java.lang.Class, and this is returned by the method getClass. There is also one java.lang.Class object describing java.lang.Class.

Think of a Class object as the "blueprint" describing a certain class from which objects are being made. It stands to reason that blueprints also need a blueprint of their own (or else how would engineers know how to make blueprints).

These statements try to illustrate this.

Integer integer = 1;
Class<?> clazzInteger = integer.getClass();
System.out.println( "class of integer=" + clazzInteger );
Class<?> clazzClazzInteger = clazzInteger.getClass();
System.out.println( "class of class Integer's class=" + clazzClazzInteger );
String string = "x";
Class<?> clazzString = string.getClass();
System.out.println( "class of string=" + clazzString );
Class<?> clazzClazzString = clazzString.getClass();
System.out.println( "class of class String's class=" + clazzClazzString );

Output:

class of integer=class java.lang.Integer
class of class Integer's class=class java.lang.Class
class of string=class java.lang.String
class of class String's class=class java.lang.Class

A class has a name, just like anything described by a blueprint has a name which is not to be confused with the blueprint itself. If a class object appears in a certain context, its toString() method is called implicitly, and this returns the class' name. If you'd like to print all the nitty-gritty details of a class (akin to printing the blueprint itself) you'd have to write a lot of code - just look at the javadoc for java.lang.Class: there's an awful lot of information to be retrieved (as befits a blueprint).

laune
  • 31,114
  • 3
  • 29
  • 42
1

At this point, we need to differentiate between a type and an instance of the type. Lets explain it with an example.

    public class A {
        public static void main(String[] args) {
            Class<A> typeInformation = A.class; //Type information associated with type `A`
            A instanceOfA = new A();  //actual instance of type `A`
        }   
    }

Type

The reference 'typeInformation' in the above code is of the type Class keeping aside the generics for a while. This information will typically be residing in non-heap memory section. Following information is store against each of the type jvm loads :

  • The fully qualified name of the type
  • The fully qualified name of the type's direct superclass (unless the type is an interface or class java.lang.Object, neither of which have a superclass)
  • Whether or not the type is a class or an interface
  • The type's modifiers ( some subset of` public, abstract, final)
  • An ordered list of the fully qualified names of any direct superinterfaces

Instance

instaneOfA is a reference to the actual instance of the type A which points to an address in the heap memory.

Return type of getClass() is a generic Class type. Like many other types available in java - String, Integer etc, Class is also a type representing the type information associated.

toString() method is associated and invoked on an instance of the Dog class, not on the Dog type itself.

//Class<Dog> dd = new Dog(); Compile time error

This is due to Type mismatch occuring while assigning the result of expression in the right hand side to the Left Hand Side, which is not of the same type. Class dd refers to a reference of Class type. Dog is a different type altogether, and a new Dog() can be assigned to a reference of the type 'Dog'.

This link will help you understand the design aspects of java runtime environment

deepak marathe
  • 409
  • 3
  • 10
0

I have an answer for your Question 3,

This gives compile time error because

Reason 1: For a Class instance, You can only assign class object that represents the Dog class, but you can't assign the Dog class object directly.

For example: Class dd=Dog.class or Class dd=Class.forName("Dog"); is correct syntax.

Reason 2: The class Class is a final class but not a super class for Dog class. You go back to the concept of dynamic method dispatch in java,where you can only assign subclass objects to a superclass variable.