关于Java平台无关性你该知道这些

一、什么是平台无关性

  • Java语言是一款跨平台的语言,不管是在windows还是在Linux又或者是mac os,它都可以支持并在上边运行,秉持着一次编译,随处运行(Compile Once,Run Anywhere)的原则。
  • Java程序可以编译成.class二进制文件,通过ClassLoader装载进系统,然后由各个平台的JVM(Java虚拟机)解析进行连接、初始化等操作,从而达到不改变程序代码实现各个平台运行的目的,这也是Java迅速风靡、建立庞大生态圈的一个重要原因。

二、平台无关性的实现

具体流程大概就是

  1. xxx.java文件进行编译生成xxx.class(JVM所能理解的字节码文件文件),这也是跨平台的基础
  2. 很多平台都有匹配JVM虚拟机,CLassLoader将.class文件装载进JVM
  3. JVM对.class文件进行解析,转换成特定平台的执行指令
    在这里插入图片描述

我们举个小例子

package com.mtli.javabasic;

/**
 * @Description:平台无关性测试
 * @Author: Mt.Li
 * @Create: 2020-04-25 08:55
 */
public class ByteCodeSample {
    public static void main(String[] args) {
        int i= 1,j=5;
        // 故意写错,看javac信息
        i++;
        ++j;
        System.out.println(i);
        System.out.println(j);
    }
}

在idea的Terminal或者系统cmd中对java程序进行编译(我这里用的是idea)

Terminal用bash/内嵌cmd运行cd java_basic/src/com/mtli/javabasic,然后javac ByteCodeSample.java,我们来看看结果
在这里插入图片描述
编译不通过,我们对源码进行修改:

package com.mtli.javabasic;

/**
 * @Description:
 * @Author: Mt.Li
 * @Create: 2020-04-25 08:55
 */
public class ByteCodeSample {
    public static void main(String[] args) {
        int i= 1,j=5;
        // 故意报错,看javac信息
        //i++++;
        i++;
        ++j;
        System.out.println(i);
        System.out.println(j);
    }
}

再次编译,发现.java下边生成了.class文件
在这里插入图片描述
然后在javabasic目录下执行该class文件:java com.mtli.javabasic.ByteCodeSample,结果如下:
在这里插入图片描述
有的人会问为什么.class文件点进去能看到源码呢?不应该是字节码文件吗?那是因为我们查看的时候,idea自动为我们进行反编译了,想看字节码的可以去资源目录里面找到该文件,打开后:
在这里插入图片描述
为了更方便我们剖析,我们使用javap -c com/mtli/javabasic/ByteCodeSample进行反汇编:

Compiled from "ByteCodeSample.java" // 由ByteCodeSample.java编译而来
public class com.mtli.javabasic.ByteCodeSample {
  public com.mtli.javabasic.ByteCodeSample(); // 无参构造函数,下面的code就是无参构造执行的内容
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Obj // 执行super
ect."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1 // 常量1放到栈顶
       1: istore_1 // 将栈顶的值放到局部变量i中(出栈)
       2: iconst_5 // 将5放到栈顶
       3: istore_2 // 将栈顶的值放到j中
       4: iinc          1, 1 // 变量1+1
       7: iinc          2, 1 // 变量2+1
      10: getstatic     #2   // 获取静态域               // Field java/lang/System.out:Ljava/io/PrintStream;
      13: iload_1  // 将变量1放到栈顶(入栈)
      14: invokevirtual #3   // 打印               // Method java/io/PrintStream.println:(I)V
      17: getstatic     #2   // 获取静态域               // Field java/lang/System.out:Ljava/io/PrintStream;
      20: iload_2
      21: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      24: return
}

回到正题,我们接下来将.class文件放到服务器上(linux)上面执行(linux得预先安装linux版本的jdk1.8x,我的是win下1.8x下编译的,服务器也要装1.8x,只要是1.8就行),首先我们需要创建好包,也就是创建对应的文件夹了
在这里插入图片描述

我比较懒,直接将src放上去了,然后回到命令行,cd /src——>java com.mtli.javabasic.ByteCodeSample,可以看到
在这里插入图片描述
我们源码是没有改动的,通过linux平台匹配的JVM就可以直接运行,可以说Java语言移植性是很不错的。

三、为什么JVM不直接将源码解析成机器码去执行

讲到这里,可能有的朋友会有这个疑惑,编译过程是比较繁琐的,需要进行各种检查,如果把这个事儿都交给JVM干,别个不得累死,直接把它看得懂的文件给它不更好吗。再说了,统一成字节码文件给JVM也有利于其他语言的兄弟移植啊。总结成两点:

  • 避免繁琐的准备工作即每次执行都要各种检查
  • 兼容性:也可以将别的语言解析成字节码
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值