Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does getClass in Java work

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.
like image 782
Number945 Avatar asked Oct 03 '15 05:10

Number945


2 Answers

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

like image 54
laune Avatar answered Sep 18 '22 14:09

laune


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

like image 21
deepak marathe Avatar answered Sep 20 '22 14:09

deepak marathe