包就是把许多类放在一起打的压缩包
JVM的工作很简单:
- 执⾏行行一个类的字节码
- 在类路径(Classpath)中找类,全限定类名是类的唯一标识
- 假如这个过程中碰到了了新的类,加载它
- 传递性依赖,你依赖的类还依赖了了别的类
Maven--包管理
- 约定优于配置
- maven中央仓库
- 按照一定的约定存储包
- Maven的本地仓库
- 默认位于~/.m2
- 下载的第三⽅方包放在这⾥里里进⾏行行缓存
- Maven的包
- 按照约定为所有的包编号,⽅方便便检索
- groupId/artifactId/version
- 按照约定为所有的包编号,⽅方便便检索
解决maven的包冲突
在看到这四个异常排查看是否是包冲突
1. AbstractMethodError
2. NoClassDefFoundError
3. ClassNotFoundException
4. LinkageError
找到冲突的包和原因
查看依赖tree
mvn dependency:tree
重定向到一个文件中
mvn dependency:tree > d.txt
查看依赖tree定位包,从maven中央仓库可以查看包里面的代码
- 方法1
利用就近原则,让能解决冲突的包更近 - 方法2
排除法,用exclusions在对应的依赖排除掉
便捷方式使用 IDEA插件:maven helper
scope的作用域
<scope>test</scope>
只在test目录有效
<scope>compile</scope>
在test和main目录都有效
<scope>provided</scope>
只在编译main代码的时候有效,运行的时候没效
练习题
要掌握在生产环境中,没有IDEA的情况下排查包的冲突,了解命令行做了什么,知道原理才能定位到问题所在,多点耐心和仔细排查。
扩展:语义化版本
Maven实战优先看:坐标和依赖/⽣生命周期/仓库/聚合和继承
「资料来源:饥人谷」
版本比较网上找的另外一个demo
public static int compare2(String v1,String v2){
int i=0,j=0,x=0,y=0;
int v1Len=v1.length();
int v2Len=v2.length();
char c;
do {
while(i<v1Len){//计算出V1中的点之前的数字
c=v1.charAt(i++);
if(c>='0' && c<='9'){
x=x*10+(c-'0');//c-‘0’表示两者的ASCLL差值
}else if(c=='.'){
break;//结束
}else{
//无效的字符
}
}
while(j<v2Len){//计算出V2中的点之前的数字
c=v2.charAt(j++);
if(c>='0' && c<='9'){
y=y*10+(c-'0');
}else if(c=='.'){
break;//结束
}else{
//无效的字符
}
}
if(x<y){
return -1;
}else if(x>y){
return 1;
}else{
x=0;y=0;
continue;
}
} while ((i<v1Len) || (j<v2Len));
return 0;
}