2020/2/24学习笔记-day04

java-day4

目录

java-day4

早上

第一节课

一个java类有两个名字

一个jar包中调用另一个包中的代码

第二节课

java文件和class文件存放的规则

 把bin下目录全部打包,不包含目录

步骤总结

第三节课

接上一节课

下午

第一节课

一个带包的类A怎么样调用不带包的类B

设置classpath

class文件被JVM加载

第二节课

类加载器是什么?

类加载器的种类

JVM中将类加载器分为以下几种

第三节课

类加载器的结构【通过调用API查找验证】


早上

第一节课

一个java类有两个名字

1、全限定名
2、简单类名

例如有这么一个类

package com. briup.test;
public class Hello{
    //..
}
​
//简单类名:Hello
//全限定名: com. briup. test. Hello

一个jar包中调用另一个包中的代码

例如:
    Hello.class 调用了Person.class 以及NumberUtil.class
    Hello.class在hello.jar中
    Person.class在person.jar中
    NumberUtil.class在c.jar中
    
    hello.jar是一个直接运行的jar包
    需要在hello.jar的MF文件进行设置
------------------------------------------- 
Manifest-Version: 1.0
Created-By: 1.8.0_ 74 (Oracle Corporation)
Main-Class: com.xxx.Hello
Class-Path: person.jar c.jar
​
-------------------------------------------
注意:
1、最后一个空行
2、我们可以说hello.jar依赖于person.jar和c.jar
3、这时候需要把hello.jar、person.jar、c.jar放在文件夹下
(除非MF文件不是这样子配置的)
4、如果MF中Class-Path: jar/person.jar jar/c.jar
(person.jar和c.jar都在jar文件夹下)

 具体步骤:

1、通过命令,将三个class文件导包
例如:
jar -cvf hello.jar hello.class
​
2、将其中两个jar包放在jar文件夹下
​
3、将其中的hello的jar包的MF文件进行如下修改
Main-Class:com.xxx.Hello
Class-Path: jar/person.jar jar/c.jar
​
4、运行hello.jar
java -jar hello.jar

第二节课

java文件和class文件存放的规则

Xxxx. java源文件存放到src目录
Xxxx.class节码文件存到bin目录
​
注意:这不是强制要求,而是编程规范

 把bin下目录全部打包,不包含目录

 

步骤总结

当前在test目录,test目录 下有三个字目录: bin jar src
1. javac -d bin src/Person. java
2. set classpath=bin
    注意:为了让第四部操作可以运行成功
3. echo %classpath%
4. java com.xxx.Person
5. jar -cvf person.jar -C bin .
6. person.jar包的MF Main-class: com.xxx.Person
7. java -jar person.jar [成功]
8. 把person.jar剪切到jar目录
9. 再次执行java -jar person.jar [失败]
   [原因是当前test目录中已经没有了person.jar了]
10.java -jar jar/person.jar [成功]
   [原因是当前test目录中加入指定目录路径]

第三节课

接上一节课

11. 删除bin下的com为文件夹(对于person.jar文件的使用无歧义)
12. javac -d bin src/Hello.java【报错】
    原因:找不到NumberUtil和Person类
13. echo %classpath%
    检查配置是否有问题
    思考1:看bin目录能否找到NumberUtil和Person类
    思考2:NumberUtil和Person类在哪
    得出1:Person在jar/person.jar,NumberUtil在jar/c.jar里面
    得出2:应该把两个路径配置到classpath中
14. 配置classpath
15. echo %classpath%
16. 去bin目录下检查是否真的生成了bin\com\xxx\Hello.class
17. java com.xxx.Hello[正常运行]
    原因:
        Hello是我们正常编译产生的一个带包的java类
        Hello类中有程序入口的编写
        Hello中使用到了别人的代码
        并且这两个类都在bin目录下
18. 打包hello.jar  jar -cvf hello.jar -C bin .
    注意:hello.jar中只有hello.class
19. 删除bin中的com/xxx/Hello.class[避免歧义]
20. hello.jar剪切到jar目录中
21. 再次执行java -jar hello.jar [失败]
22. 修改了jar/hello.jar中MF文件
-------------------------
Manifest-Version:  1.0
Created-By:  1.8.0_74  (Oracle  Corporation)
Main-Class:  com.xxx.Person
​
-------------------------
​
23. 再运行java  -jar  jar/hello.jar
报错:Hello找不到    ClassNotFoundException
原因:hello.jar中的Hello类使用到了person.jar中的代码,但是没有在MF中进行配置
​
​
24. 再次修改jar/hello.jar中MF文件
-------------------------
Manifest-Version:  1.0
Created-By:  1.8.0_74  (Oracle  Corporation)
Main-Class:  com.xxx.Hello
Class-Path:  Person.jar  c.jar  
​
-------------------------
​
25. 再次运行java  -jar  jar/hello.jar
    执行成功
    注意:person.jar  hello.jar  c.jar  这三个jar包的位置,他们都在jar目录中
​
​

下午

第一节课

一个带包的类A怎么样调用不带包的类B

老版本JDK可以调用,从JDK1.4(包含)往后,编译器在这样的情况会报错

  

设置classpath

永久生效:
    在我的电脑->属性->高级系统设置->环境变量
    
当前命令行窗口生效:
    set classpath=bin
    注意:当前窗口关闭,该变量的临时设置就失效了
​
当前命令一次生效:
    java -classpath bin Hello
    简写为:java -cp bin Hello
    注意:当前命令执行完,该变量的临时设置就失效了

class文件被JVM加载

注意:任何代码要想被运行,必须先从磁盘中加载到内存中去才行。
​
JVM启动后,会创建一些类加载器,然后让这些类加载器去加载当前代码所需要的东西。
​
类加载器的作用:在JVM内来加载java类的

第二节课

类加载器是什么?

类加载器本质上也是一段代码,这段代码加载后可以把指定位置的java类从磁盘中读取到内存。

类加载器的种类

类加载器上一个总称,它下面有很多不同种类特点的个性化类加载器。在java中称ClassLoader,同时ClassLoader也是Java SE API提前写好的一个类,这个类用来代表类加载器的,相当于我们写了一个类Person用这个Person来代表人一样的效果。
​
ClassLoaderl类--->代表类加载器

JVM中将类加载器分为以下几种

启动类加载器  bootstrapClassLoader
            【不是java代码实现的】
任务:加载jdk lib里面的指定jar包(如rt.jar)
C:\Program Files\Java\jdk1.8.0_74\jre\lib
在java中,使用这个变量来代表启动类加载路径:
sun.boot.class.path
当前我电脑路径:
C:\Program Files\Java\jdk1.8.0_74\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\rt.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\sunrsasign.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\charsets.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_74\jre\classes
​
​
扩展类加载器  ExtClassLoader
任务:加载jdk lib\ext里面的指定jar包
C:\Program Files\Java\jdk1.8.0_74\jre\lib\ext
在java中,使用这个变量来代表扩展类加载路径:
java.ext.dirs
当前我电脑路径:
C:\Program Files\Java\jdk1.8.0_74\jre\lib\ext
C:\Windows\Sun\Java\lib\ext
​
应用类加载器  AppClassLoader
任务:加载classpath配置路径下的jar包
在java中,使用这个变量来代表应用类加载路径:
java.class.path
当前我电脑路径:....
​
自定义类加载器 
​
注意:这些可以表现不同类加载器的加载路径的加载变量,在JVM运行的代码之后,通过系统变量的形式,提前收集好了,并且提供API供我们调用

第三节课

类加载器的结构【通过调用API查找验证】

public class ClassLoaderTest{
    
    public static void main(String[] args){
        
        //Properties p = System.getProperties();
        
        //p.forEach((k,v)->System.out.println(k+"\t"+v));
        
        ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
            
        System.out.println(appClassLoader);
​
        ClassLoader c=appClassLoader.getParent();
​
        System.out.println(c);
    }
​
}

 

注意:

启动类加载器在java中无法体现,因为他不是用java写的

类加载器之间共同协作,然后把类加载到内存去执行

启动类加载器  bootstrapClassLoader
【加载最基本的java类】
​
扩展类加载器  ExtClassLoader
【加载额外添加的一些功能】
​
应用类加载器  AppClassLoader
【加载自己编写的项目代码】
​
​
这三个类加载共同协作,使用双亲委托的方式,把class类加载到内存

  

为了避免恶意和系统中同包同名的被加载到内存,替换原有的基础类,从而导致系统崩溃的产生

可以通过双亲委托机制,将jar包放在扩展类加载器,然后直接运行

 

发布了82 篇原创文章 · 获赞 52 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/iostream992/article/details/104473744
今日推荐