java编译、运行时类型

编译期在类加载过程中的加载阶段。
运行期主要指类加载过程中的初始化阶段。

jvm加载阶段(编译期)完成以下事件:
         通过一个类的全限定名来获取定义此类的二进制字节流
         将这个字节流所代表的静态存储结构转换化为方法区的运行时数据结构
         在堆中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

编译期常量:它的值在编译期就可以确定,编译时会将用到该常量的地方替换为值。
 

public class CompileFinalTest{
    public static void main(String args[]){
        System.out.println(Data.i1);
        System.out.println(Data.i2); //initialization!
        System.out.println(Data.b1); //initialization!
        System.out.println(Data.b2);
        System.out.println(Data.s1);
        System.out.println(Data.s2); //initialization!
        System.out.println(Data.a);  //initialization!
        System.out.println(Data.e);  //initialization!
    }
}
class Data{
    static{
        System.out.println("initialization!");
    }
    public static final int i1 = 0;
    public static final Integer i2 = 0;
    public static final Boolean b1 = true;
    public static final boolean b2 = true;
    public static final String s1 = "0";
    public static final String s2 = new String("0");
    public static final A a = new A();
    public static final Enum e = E.A;
}
class A{

}
enum E {
    A,B,C,D,E,F,G;
}
结论:java中的编译期常量包括java八大基本类型和直接声明的string类型:如String name = “andy”。

Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型,编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定,如果编译时类型和运行时类型不一致,会出现所谓的多态。因为子类其实是一种特殊的父类,因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,或者被称为向上转型,由系统自动完成

引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法,因此,编写Java代码时,引用变量只能调用声明该变量所用类里包含的方法。与方法不同的是,对象的属性则不具备多态性。通过引用变量来访问其包含的实例属性时,系统总是试图访问它编译时类所定义的属性,而不是它运行时所定义的属性。

绑定:将一个方法调用同方法主体关联起来叫做绑定!

前期绑定:在程序执行之前进行绑定(如果有的话,由编译器和连接器完成),前期绑定是面向过程程序设计语言中默认的绑定方式,例如,C语言只有一种方法调用,那就是前期绑定。

后期绑定:就是在程序运行时根据对象的类型进行绑定,也叫作动态绑定或运行时绑定。

注意:Java中除了static和final方法(private方法属于final方法,因为类中的private方法被隐式指定为final方法,由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)之外,其他方法都是后期绑定。这意味着通常不必判定是否该进行后期绑定,因为它是自动发生的。

执行案例:1.子类方法覆盖父类方法( 子类重写父类中的方法,调用子类中的方法),子类没有重写父类中的方法,所以到父类中寻找相应的方法。动态绑定只是针对对象的方法,对于属性无效。因为属性不能被重写。

对于父类声明子类引用,属性调用取决于该引用变量的声明时类型,调用父类属性,如果private编译器将报错。子类的变量并不会覆盖父类的变量!相当于子类中存在两个同名属性!


1.方法重载是在编译时执行:编译期调用重载方法已被确定
2.方法重写是在运行时确定
3.泛型(类型检测)发生在编译时
4.注解即有可能是运行时也有可能是编译时。
@Override编译时注解,在编译时会检查一些简单的如拼写的错误(与父类方法不相同)等
@Test是junit框架的注解,他是一个运行时注解
5.异常即有可能是运行时异常,也有可能是编译时异常
运行时异常由jvm抛出,如空指针,索引越界等等
编译时异常一般通过try catch捕获
6.继承编译时执行,编译后就已经确定
7.代理(delegate):也称动态代理,是在运行时执行

猜你喜欢

转载自blog.csdn.net/jiangtianjiao/article/details/87819458