zoukankan      html  css  js  c++  java
  • 静态分配

    静态方法会在类加载期就进行解析,而静态方法显然也是可以拥有重载版本的,选择重载版本的过程也是通过静态分派完成的。

    public class StaticDispatch{
    
        public void sayHello(Human guy){
            System.out.println("hello,guy!");
        }
        public void sayHello(Man guy){
            System.out.println("hello,gentleman!");
        }
        public void sayHello(Woman guy){
            System.out.println("hello,lady!");
        }
        public static void main(String[]args){
            Human man=new Man();
            Human woman=new Woman();
            StaticDispatch sr=new StaticDispatch();
            sr.sayHello(man);
            sr.sayHello((Man)man);
            sr.sayHello((Woman) woman);
    }
    }

    //结果

    hello,guy!
    hello,guy!
    hello,gentleman!
    hello,lady!

    我们把上面代码中的“Human”称为变量的静态类型(Static Type),或者叫做的外观类型(Apparent Type),后面的“Man”则称为变量的实际类型(Actual Type),静态类型和实际类型在程序中都可以发生一些变化,区别是静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,并且最终的静态类型是在编译期可知的;而实际类型变化的结果在运行期才可确定,编译器在编译程序的时候并不知道一个对象的实际类型是什么。

    所有依赖静态类型来定位方法执行版本的分派动作称为静态分派。静态分派的典型应用是方法重载静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的。 

    下面的代码更适合演示在编译期间确实调用方法的版本

    public class maintest {
        public static void sayHello(Object arg) {
            System.out.println("hello Object");
        }
    
        public static void sayHello(int arg) {
            System.out.println("hello int");
        }
    
        public static void sayHello(long arg) {
            System.out.println("hello long");
        }
    
        public static void sayHello(Character arg) {
            System.out.println("hello Character");
        }
    
        public static void sayHello(char arg) {
            System.out.println("hello char");
        }
    
        public static void sayHello(char... arg) {
            System.out.println("hello char……");
        }
    
        public static void main(String[] args) {
            sayHello('a');
        }
    }

    执行结果: 

    //执行结果
    hello char
    
    对应字节码
             0: bipush        97
             2: invokestatic  #10                 // Method sayHello:(C)V
             5: return

    这很好理解,'a'是一个char类型的数据,自然会寻找参数类型为char的重载方法,如果注释掉sayHello(char arg)方法,那输出会变为:

    //hello int
    //对应字节码
    
             0: bipush        97
             2: invokestatic  #9                  // Method sayHello:(I)V
             5: return

    这时发生了一次自动类型转换,'a'除了可以代表一个字符串,还可以代表数字97(字符'a'的Unicode数值为十进制数字97),因此参数类型为int的重载也是合适的。

    我们继续注释掉sayHello(int arg)方法,那输出会变为:

    hello long
    
    //对应字节码
             0: ldc2_w        #8                  // long 97l
             3: invokestatic  #10                 // Method sayHello:(J)V
             6: return

    实际上自动转型还能继续发生多次,按照char->int->long->float->double的顺序转型进行匹配.

  • 相关阅读:
    陈天桥:重点布局影音文娱业务及海内市场
    瑞信维持新浪跑赢大盘评级
    快讯:空中网第四季度净利501万美元同比涨148%
    传高盛与德劭前合伙人组5亿美元私募基金
    CodeFirst 关系创建——Fluent API配置多重关系,关闭级联删除的方法
    笔记:IE下 jquery的fadeIn与fadeOut方法失效的BUG
    Codefirst Fluent API创建关系
    javascript拖动效果的一个注意事项:拖动图片时,mousemove事件会被中断
    通过下拉菜单筛选GridPanel的数据【转】
    as3.0学习笔记——坐标轴、并记录画图所犯的两个低级错误
  • 原文地址:https://www.cnblogs.com/snow-man/p/10609317.html
Copyright © 2011-2022 走看看