package com.briup.test2;
public class Hello{
public static void main(String[] args){
Hello.say();
}
public static void say(){
System.out.println("Hello World");
}
}
package com.briup.test1;
import org.apache.commons.lang3.math.NumberUtils;
import com.briup.test2.Hello;
public class Person{
public static void main(String[] args){
Hello.say();
int a=NumberUtils.max(1,5,3);
System.out.println(a);
}
}
注意:一个带包的类A调用不带包的类B,在老版本JDK可以调用,JDK1.1 1.2 1.3 可以用,从JDK1.4开始,编译器会报错
设置classpath的方法
1)永久生效 :在我的电脑-》属性-》高级系统设置-》环境变量
2)当前命令窗口生效:set classpath=【路径】(cmd窗口关闭就失效)
3)当前命令一次生效:
java -classpath bin Hello
简写为 java -cp bin Hello
class的打包
使用jar命令,就可以完成class的打包工作,打包完成只会,jar中不仅有class文件,还有一些对当前jar做出描述的文件。/META-INF目录下生产一个MF文件
默认情况下,这个jar是不能直接运行的,也就是它不是一个可执行jar包,我们可以通过对MF文件的修改,让它变成一个可执行的jar包,前提是这个jar中的class文件里面的类中有程序入口。
修改方式:在MF文件中添加一行内容,格式为key: value
Main-Class: 包名.类名
如果没有包,那么就直接写这个类,但是这个类里面一定要有程序入口。
jar包的打包方式
把当前目录下的Hello.class打到hello.jar这个jar包中
jar -cvf hello.jar Hello.class
把当前目录下的Hello.class Person.class打到hello.jar这个jar包中
jar -cvf hello.jar Hello.class Person.class
把当前目录下的所有的class打到hello.jar这个jar包中
jar -cvf hello.jar *.class
把当前目录下的briup文件夹里面的所有文件打到这个jar包中,同时【包含】briup目录本身
jar -cvf hello.jar briup
把当前目录下的briup文件夹里面的所有文件打到这个jar包中,但是【不包含】briup目录本身
jar -cvf hello.jar -C briup .
运行jar包
比如要运行Hello.class文件打包后生成的jar包,就需要现在jar包的MF文件这样配置
MF文件中的配置:
Manifest-Version: 1.0
Created-By: 1.8.0_131 (Oracle Corporation)
Main-Class: com.briup.test2.Hello
注意,最后要空一行
如果要运行Person.class打的jar包应如何配置
由于Person.java中使用了Hello类与NumberUtils类的方法
person.jar中的MF文件应这样配置
Manifest-Version: 1.0
Created-By: 1.8.0_131 (Oracle Corporation)
Main-Class: com.briup.test1.Person
Class-Path: hello.jar commons.jar
运行结果如图所示
注意1,最后一个空行必须要加
注意2,这个时候我们可以说person.jar依赖于hello.jar和commons.jar
注意3,这时候需要把person.jar、hello.jar、commons.jar放在同一个目录下,因为MF文件中是这样配置的:Class-Path: hello.jar commons.jar
注意4,如果MF中这样配置:Class-Path: jar/hello.jar jar/commons.jar ,那么就说明hello.jar和commons.jar需要在jar这个目录中,然后jar这个目录和person.jar放在同一个路径中
class 文件被JVM加载。
注意:任何代码想要被运行,都必须先从磁盘中加载到内存中才行
JVM启动后,会创建一些类加载器,然后让这些类加载器去加载当前代码运行所需要的类
类加载器的作用:就是在JVM中来加载j硬盘上编译好的java类。``
**类加载器**
```java
类加载器本质上也是一段代码,这段代码执行后,可以指定位置上把编译好的java类从硬盘读取到内存
类加载器的种类
- 启动类加载器(不是java语言实现的) bootstrapClassLoader 加载路径:C:\Program Files\Java\jdk1.8.0_131\jre\lib 自动加载这个路径下指定的jar,如rt.jar
- 扩展类加载器 ExtClassLoader (加载路径: C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext 自动加载这个路径下的jar包)
- 应用类加载器 AppClassLoader(加载路径: 环境变量classpath中设置的所有路径的class文件)
- 自定义类加载器 XXXClassLoader
AppClassLoader->ExtClassLoader->bootstrapClassLoader
多个类加载器共同协作,然后把我们编写的类加载到内存中运行,这种方式叫”双亲委托“
双亲委派机制的工作流程:
- 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。
每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
-
当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
-
当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。