方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期是不可改变的。换句话说,调用目标在程序代码写好、编译器进行编译那一刻就已经确定下来。这类方法的调用被称为解析( Resolution )。
只要能被 invokestatic 和 invokespecial 指令调用的方法,都可以在解析阶段中确定唯一的调用版本,Java 语言里符合这个条件的方法共有静态方法、私有方法、实例构造器、父类方法 4 种,再加上被 final 修饰的方法(尽管它使用 invokevirtual 指令调用),这 5 种方法调用会在类加载的时候就可以把符号引用解析为该方法的直接引用。这些方法统称为“非虚方法”( Non-Virtual Method ),与之相反,其他方法就被称为“虚方法”( Virtual Method )。
以上内容出自周志明先生的《深入 JVM (第三版)》,结合两段内容可以推论『父类方法是在程序代码写好、编译器进行编译那一刻就已经确定下来的』,我本来是从字面上理解就是父类中的方法,但父类中的方法应该不具备这么腰椎盘突出的性质吧。。。
谢谢
1
codehz 2020-09-22 20:53:19 +08:00
所有能写出来的方法都是编译期可知,运行期不变啊,除非你用 asm 库动态创建,但是创建的过程逻辑上也是编译期(
你在不绕过 jvm 的情况下能写出运行期可变的 java 方法吗( |
2
Newyorkcity OP @codehz
```java import java.util.Random; public class Main { public static void main(String[] args) { final Random random = new Random(); Human person = random.nextBoolean() ? new Man() : new Woman(); person.say(); } static abstract class Human { abstract void say(); } static class Man extends Human { @Override void say() { System.out.println("I am male."); } } static class Woman extends Human { @Override void say() { System.out.println("I am female"); } } } ``` |
3
codehz 2020-09-23 00:40:07 +08:00 via Android
@Newyorkcity 哦,我理解错了,看题目我以为是类的问题
|