尚硅谷2020最新版宋红康JVM教程-中篇-第1章Class文件结构-1-字节码文件的跨平台性

字节码文件的跨平台性

Java语言:跨平台的语言(write once,run anywhere)

  • 当Java源代码成功编译成字节码后,如果想在不同的平台上面运行,则无须再次编译。
  • 这个优势不再那么吸引人了,Python、PHP、Perl、Ruby、Lisp等有强大的解释器。
  • 跨平台似乎已经快成为一门语言必选的特性。

Java虚拟机:跨语言的平台

  • Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格所关联。无论使用何种语言进行软件开发,只要能将源文件编译为正确的Class文件,那么这种语言就可以在Java虚拟机上执行。可以说,统一而强大的Class文件结构,就是Java虚拟机的基石、桥梁。

在这里插入图片描述

  • 所有的JVM全部遵守Java虚拟机规范,也就是说所有的JVM环境都是一样的,这样一来字节码文件可以在各种JVM上运行。
    在这里插入图片描述

Java源码必须要被编译为符合JVM规范的字节码

  • 前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件。
  • javac是一种能够将Java源码编译为字节码的前端编译器。|
  • Javac编译器在将Java源码编译为一个有效的字节码文件过程中经历了4个步骤,分别是词法解析、语法解析、语义解析以及生成字节码。
    在这里插入图片描述

Oracle的JDK软件包括两部分内容:

  • 一部分是将Java源代码编译成Java虚拟机的指令集的编译器
  • 另一部分是用于实现Java虚拟机的运行时环境

Java的前端编译器

在这里插入图片描述

  • Java源代码的编译结果是字节码,那么肯定需要有一种编译器能够将Java源码编译为字节码,承担这个重要责任的就是配置在path环境变量中的javac编译器。javac是一种能够将Java源码编译为字节码的前端编译器。
  • HotSpot VM并没有强制要求前端编译器只能使用javac来编译字节码,其实只要编译结果符合JVM规范都可以被JVM所识别即可。
  • 在Java的前端编译器领域,除了javac之外,还有一种被大家经常用到的前端编译器,那就是内置在Eclipse中的ECJ(Eclipse Compiler for Java)编译器。和Javac的全量式编译不同,ECJ是一种增量式编译器。
    • 在Eclipse中,当开发人员编写完代码后,使用“Ctrl+s”快捷键时,ECJ编译器所采取的编译方案是把未编译部分的源码逐行进行编译,而非每次都全量编译。因此ECJ的编译效率会比javac更加迅速和高效,当然编译质量和javac相比大致还是一样的。
    • ECJ不仅是Eclipse的默认内置前端编译器,在Tomcat中同样也是使用ECJ编译器来编译jsp文件。由于ECJ编译器是采用GPLv2的开源协议进行源代码公开,所以,大家可以登录eclipse官网下载ECJ编译器的源码进行二次开发。·默认情况下,Intellij IDEA使用javac编译器。(还可以自己设置为Aspect]编译器ajc)
  • 前端编译器并不会直接涉及编译优化等方面的技术,而是将这些具体优化细节移交给HotSpot的JIT编译器负责。

透过字节码指令看代码细节

BAT面试题

①类文件结构有几个部分?
②知道字节码吗?字节码都有博些?Integerx=5;inty=5;比较x==y都经过哪些步骤?

代码1

public class IntegerTest {
    public static void main(String[] args) {
//        // Integer变量和int变量比较时,只要两个变量的值是向等的(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较)
//        Integer x = 5;
//        int y = 5;
//        System.out.println(x == y); // true
//
//        // 同上
//        Integer x2 = new Integer(5);
//        int y2 = 5;
//        System.out.println(x2 == y2); // true
//
//        // 两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true
//        Integer a1 = 1;
//        Integer b1 = 1;
//        System.out.println(a1 == b1); // true
//
//        // 同上
//        Integer a3 = 128;
//        Integer b3 = 128;
//        System.out.println(a3 == b3); // false
//
//        // 非new生成的Integer变量和new Integer()生成的变量比较时,结果为false
//        // 当变量值在-128~127之间时,非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象
//        Integer a2 = new Integer(1);
//        Integer b2 = 1;
//        System.out.println(a2 == b2); // false
//
//        // 两个通过new生成的Integer变量永远是不相等的
//        Integer a4 = new Integer(1);
//        Integer b5 = new Integer(1);
//        System.out.println(a4 == b5); // false


        Integer x = 5;
        int y = 5;
        System.out.println(x == y); //true

        Integer i1 = 10;
        Integer i2 = 10;
        System.out.println(i1 ==i2); //true

        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i3 ==i4); //false


    }
}

在这里插入图片描述

代码2

public class StringTest {
    public static void main(String[] args) {
        String a1 = new String("hello") + new String("world");
        String a2 = "helloworld";
        System.out.println(a1 == a2); //false
    }
}

在这里插入图片描述

具体可看 尚硅谷2020最新版宋红康JVM教程-13-String Table

代码3

// 成员变量的赋值过程:1 默认初始化 2 显式初始化 3 构道器中初始化。有了对象之后,可以“对象.属或”对象.方法”的方式对成员变量进行赋值。
class Father {
    int x = 10;

    public Father() {
        this.print();
        x = 20;
    }

    public void print() {
        System.out.println("father.x=" + x);
    }
}

class Son extends Father {
    int x = 30;

    public Son() {
        this.print();
        x = 40;
    }

    public void print() {
        System.out.println("son.x=" + x);
    }
}

public class SonTest {
    public static void main(String[] args) {
//        Father f = new Father();
//        System.out.println(f.x);
        //father.x=10
        //20

        Father f = new Son();
        System.out.println(f.x);
        //son.x=0  先执行Father,执行print时,靠近原则执行了Son的print
        //son.x=30 Son类,显式初始化,x=30,Son的print执行
        //20  父类引用型变量持有子类对象时,属性值看应用型变量
    }
}

在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值