javainheritancedynamicstatic

Difference between dynamic and static type assignments in Java


Given the follow class hierarchy what are the dynamic and static types for the following statements?

Class hierarchy:

class Alpha {}

class Beta extends Alpha {}

class Gamma extends Alpha {}

class Epsilon extends Alpha{}

class Fruit extends Gamma{}

class Golf extends Beta {}

class Orange extends Fruit{}

For each of the following statements, what's the static type and dynamic type?

Fruit f = new Fruit();
Alpha a = f;
Beta b = f;
a = b;
Gamma g = f;

My answers/questions:

However I do not know the other two answers:


Solution

  • I understand that Fruit f = new Fruit() will be of both static and dynamic type Fruit.

    I think you are confusing a bit the terms "static" and "dynamic" types with compile-time and run-time types (or as in C++ when you assign the address of a object of type A to a pointer of type B with B being the parent class of A.)

    Barring reflection tricks, there is no dynamic typing in Java. Everything is statically typed at compile time. The type of an object at run-time is the same as the one it got compiled to.

    What is happening is that you are confusing object references (a, b, c, f) with actual objects instantiated in the heap (anything created with new.)

    In Java, f is an object reference, not the object itself. Moreover, the reference type of f is Fruit and sub-classes of it. The object (new Fruit()) that you assign to it happens to be of type Fruit.

    Now all the other references in your sample code, a is of type "reference to A and sub-classes of it"; b is of type "reference to B and sub-classes of it"; etc, etc.

    Keep this in mind because it is very important.

    Alpha a = f; Will be of type Alpha at at compile time (static) and type Fruit at runtime (dynamic).

    a is of type "reference to type A and sub-classes". f is of type "reference to type Fruit and sub-classes".

    The object f points to is of type 'Fruit'. When you say a = f you are not assigning f to a. You are saying "a now will reference that thing f is currently referencing to".

    So after that assignment, what is a referencing? The object of type Fruit the object reference f pointed to at the time of assignment.

    Remember, a, b, g, f, they are not objects. They are references or handles to objects created one way or another with the new operator.

    A reference variable such as a, b or f are different beasts from the objects created with new. But it just so happen that the former can point to the later.

    The type of the object created with new at run-time is the same as the one determined at compile time.

    Gamma g = f; Will be of type Gamma at compile time (static) and type Fruit at runtime (dynamic).

    Same as above. The variable g is an object reference of type "reference to type Gamma and sub-classes". In this assignment, g is made to point to the same object pointed by f. What is the type of that object? The same given at compile time: Fruit.

    However I do not know the other two answers. Beta b = f is an instance in which two subclasses of the same super class are assigned to one another so I'm not sure if it would be of type Beta or type Alpha at compile time (static).

    b is of type "reference to type Beta and sub-classes of it". The object it points to after the assignment b = f is of type Fruit, the type it had at compile time.

    1. The type of object references a, b, g, and f is determined at compile time. They are statically typed and do not change at run-time.

    2. The type of an object created with new is also determined at compile time. They are also statically typed and do not change at run-time.

    3. The objects, the stuff object references a, b, g and f point to at run-time, that is determined by whether the statements are found valid by the compiler. The assignments can change, but that has nothing do with whether the object references or the object themselves are statically or dynamically typed.

    If you want to see a clear distinction between dynamic and static typing consider the following:

    // Java, statically typed.
    int x = 3;
    x = 5; // good
    x = "hi"; // compiler error
    
    ## Ruby, dynamically typed
    x = 3 # ok
    x = 5 # ok
    x = "hi" # still ok
    

    Then there is the distinction between strongly typed and weakly/duck typed languages (both of which can be dynamically typed.) There is plenty of literature on this subject out there.