17学Java之Java的包原理

从某种层面上来说,JVM的工作非常简单,即:

  1. 执行一个类的字节码
  2. 执行一个类的字节码过程中,碰到了一个新的类,加载它的字节码,然后重复第一步

例如下面的代码:

public class Application {

	public static void main(String [] args) { 1. 启动main程序的时候加载Application类的字节码
		A a = new A(); 2. 碰见A类实例化,加载A类的字节码
        a.hello();
        B b = new B(); 2. 碰见B类实例化,加载B类的字节码
        b.hello();
    }

}

那么问题来了,JVM去哪里加载我们的字节码呢?

答案是 类路径(ClassPath)。

我们知道,在操作系统命令行中,输入一条命令,例如java -version,

这个命令操作系统是从$PATH环境变量里的路径中一个一个找的,

所以Java中寻找字节码有点类似操作系统,用的是类路径,在我们指定的类路径下寻找我们的类。

举个栗子:

读者可以自己使用idea创建一个main程序并运行,

如上图,idea会自动输出一个很长的命令行,我们可以看到开头的命令并不陌生,

就是一个执行java这个可执行程序,后面跟了很多的参数,我们下面挑选几个比较关键的看一看,

咱们可以看到,通过idea输出的命令,我们直接放到命令行里执行,

得到的结果和使用idea的界面输出是一样的,

这也就说明了idea本质也是通过执行一些列的java命令作为基础的,

只是它把这些命令封装成可点击的按钮等等了。

命令简化一下,咱们直接 java -classpath 类所在路径 java类 , 看下图直接得到正确结果。

那下面还有一个问题,请看:

咱们自己写的代码里,并没有org.springframework.boot.SpringApplication这个类,那这个类是从哪里来的呢?

咱们通过idea点击进去,进行定位跟踪一下,会发现他在spring-boot-2.0.0.RELEASE.jar这里,

我们可以看到命令行里也恰巧在classpath后面指定了这个jar包的,那java是怎么从jar中拿到这个类并加载的呢?

首先我们到maven目录下,找到这个jar包,

随后咱们把这个jar的后缀名,改为zip,并且进行解压,

好,根据上面的操作,我们根据包名+类名在这个zip里找到了这个类,其实jar包就类似我们的zip包,JVM会把jar包解压后,然后从解压后的目录里找到响应需要加载的类进行加载。

总结一下:

  1. JVM从-classpath/-cp指定的jar或者路径中进行查找类。
  2. 类的全限定名确定了一个独一无二的类,并且代表他所处于的目录,例如com.test.Test,Test类在其存在的jar中,文件目录就是JARPATH/com/test/Test.class。
  3. 包就是把许多类打包压缩在一起的压缩包,和zip一样,只是后缀名是jar。

接下来让我们康康,这样会有什么问题?

一个项目往往是由很多的类积少成多组装而成的,成千上万甚至几十几百万个类,数量一多,则不好管理,

我们知道类的唯一标识是类的全限定名,在我们指定的classpath中的jar和文件夹,会不会有冲突的类?

如果冲突的类有三五个,JVM的类加载顺序是加载第一个出现的同名类,万一第一个加载的类里缺少我们需要的方法或者变量,那么JVM将会直接抛出异常,导致我们的程序无法正常进行下去。

这个问题,就需要用到包管理工具了,也就是下一篇文章需要讲到的Maven包管理工具,

包管理工具的本质就是告诉JVM从哪里找到相应的类以及类库,并且解决其中的冲突关系。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值