一文读懂java静态绑定和动态绑定

前提:动态绑定和多态是息息相关的,动态的意思是在运行期间决定调用哪个函数,同时也可以不用重新编译就能够感知程序的变化

先说一下静态绑定吧

一些用static,final,private修饰的方式,在调用的时候就是使用的静态绑定方法,比如private修饰的方法,我们调用一个对象的私有方法,其实在逻辑上是肯定只有一个方法与之对应的(私有方法不能继承,没有任何的歧义),因此在编译的时候就可以确定运行哪一个方法。也可以想一下重载也是一样,没有继承关系的重载也是静态绑定。

接下来是动态绑定

先看一个例子,有一个Employee类,继承出Manager类。

public class Employee {
    private double salary;
    Employee(double salary){
        this.salary=salary;
    }

    public double getSalary(){
        return this.salary;
    }

    public static void main(String[] args) {
        Employee e=new Manager(10000,10000);
        e.getSalary();
    }
}


class Manager extends Employee{
    private double bonus;
    Manager(double salary,double bonus){
        super(salary);
        this.bonus=bonus;
    }

    public double getSalary(){
        double baseSalary=super.getSalary();
        return baseSalary+this.bonus;
    }
    public void setBonus(double bonus){
        this.bonus=bonus;
    }

    public double getBonus(){
        return this.bonus;
    }
}

这段代码就体现出了面向对象语言的多态性质,main函数里的Employee e变量可以指向任何它的子类(比如Manager类的对象,或者任何它的子类,代码中没有体现),此时如果调用了重写父类的方法,那么光靠编译器就不能知道调用哪一个子类的方法(是经理(Manager)的方法还是秘书(代码没体现)的方法),这时就需要在运行的时候通过虚拟机,判断当前的引用(即变量e)指向的对象的具体类型,在调用对应的方法(即动态绑定)。

同时,动态绑定还有一个好处,那就是如果最开始程序只有两个子类:经理和秘书,然后后来程序变动,新增程序员子类,那么不需要改变e.getSalary()这里,也不需要重新编译,就能感知到程序的变化(需要做的就是虚拟机发现没有加载这个类,将类的字节码文件加载到虚拟机即可)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我来给你解答一下。 在Java中,泛型是一种用于编写可重用代码的机制,可以让你在编译时检测类型安全性。通过使用泛型,我们可以编写出更加通用的代码,提高代码的复用性和可读性。 在Java中,泛型类型参数可以传入类、接口和方法中。在方法中传入泛型类型参数时,可以使用以下几种方式: 1. 传入具体类型参数 例如,假设我们有一个泛型方法: ```java public <T> void print(T t) { System.out.println(t); } ``` 我们可以通过以下方式传入具体类型参数: ```java print("hello world"); // 传入String类型参数 print(123); // 传入Integer类型参数 ``` 2. 传入泛型类型参数 在某些情况下,我们可能需要在方法中传入泛型类型参数。此时,可以使用以下方式: ```java public <T> void printList(List<T> list) { for (T t : list) { System.out.println(t); } } ``` 在调用该方法时,我们可以传入任何类型的List: ```java List<String> stringList = Arrays.asList("hello", "world"); List<Integer> intList = Arrays.asList(1, 2, 3); printList(stringList); // 传入String类型的List printList(intList); // 传入Integer类型的List ``` 3. 传入通配符类型参数 有时候,我们可能需要在方法中传入一个不确定类型的List。此时,可以使用通配符类型参数: ```java public void printList(List<?> list) { for (Object obj : list) { System.out.println(obj); } } ``` 在调用该方法时,我们可以传入任何类型的List: ```java List<String> stringList = Arrays.asList("hello", "world"); List<Integer> intList = Arrays.asList(1, 2, 3); printList(stringList); // 传入String类型的List printList(intList); // 传入Integer类型的List ``` 注意,使用通配符类型参数时,我们只能对List进行读取操作,不能进行添加或删除操作。 希望这些内容能够解答你的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值