What is the difference between a compile time type vs run time type for any object in Java?

我怕爱的太早我们不能终老 提交于 2019-11-28 06:37:52

Java is a statically typed language, so the compiler will attempt to determine the types of everything and make sure that everything is type safe. Unfortunately static type inference is inherently limited. The compiler has to be conservative, and is also unable to see runtime information. Therefore, it will be unable to prove that certain code is typesafe, even if it really is.

The run time type refers to the actual type of the variable at runtime. As the programmer, you hopefully know this better than the compiler, so you can suppress warnings when you know that it is safe to do so.

For example, consider the following code (which will not compile)

public class typetest{
    public static void main(String[] args){
        Object x = args;
        String[] y = x;

        System.out.println(y[0])
    }
}

The variable x will always have type String[], but the compiler isn't able to figure this out. Therefore, you need an explicit cast when assigning it to y.

Java is statically typed. That means that every expression (including variables) in the language has a type that is known at compile time according to the rules of the language. This is known as the static type (what you call "compile-time type"). The types in Java are the primitive types and the reference types.

Also, each object at runtime in Java has a "class" (here, "class" includes the fictitious array "classes"), which is known at runtime. The class of an object is the class that an object was created with.

Part of the confusion comes from the fact that each class (and interface and array type) in Java has a corresponding reference type, with the name of the class (or interface or array type). The value of a reference type is a reference, which can either be null or point to an object. The Java language is designed so that a reference of reference type X, if not null will always point to an object whose class is the class X or a subclass thereof (or for interfaces, whose class implements the interface X).

Note that the runtime class applies objects, but objects are not values in Java. Types, on the other hand, apply to variables and expressions, which are compile-time concepts. A variable or expression can never have the value of an object, because there are no object types; it can have a value of a reference that points to an object.

I think of "compile time type" as ANY type a variable can be shown to have at compile time. That would include the declared class, any superclasses, and any implemented interfaces.

At runtime, a given object only has one lowest-level class; it can legally be cast to or assigned to a variable of that class, but also to any variable of any of its subclasses or implemented interfaces. The compiler will (often, anyway) allow you to cast it to anything, but the runtime will throw an exception if you attempt to assign something that is not legal.

Once an object is assigned to the variable, then the compiler will treat it as though it is of the type of the variable. So another use of "compile time" could be the variable type, and you can get around that at compile time by casting to a different type as long as you know the cast will be legal at runtime.

If I speak of just one type, I think of the 'runtime type' of a variable as the actual bottom (top?) level subclass of the variable; the lowest sub-class to which it could be cast. But I also routinely think of any object as an instantiation of any of its legal types.

Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!