1. 类加载器
1. 1. 类加载的时机
- 1 创建类的对象时,如果类还没有加载就会加载该类的class方法进内存.
- 2 调用类的静态方法时,如果类没有加载就会加载该类的class文件进内存.
- 3 调用类的静态成员变量(静态常量除外)时,如果类没有加载就会加载该类的class文件进内存.
- 4 指定类全名通过Class调用forName方法会强制加载该类的Class文件进内存.
1. 2. 类加载器的概叙
1. 2. 1. 什么是类加载器
- 一个负责加载类的对象。
1. 2. 2 类加载器的作用
- 将类的字节码文件从硬盘中加载到内存中.并在内存中创建了一个Class对象。
- Class对象就是根据字节码文件创建出来的,Class对象就包含了类的所有信息。
- 所有类加载器的共同父类:java.lang.ClassLoader
1. 2. 3 类加载器的分类
引导类加载器:BootstrapClassLoader
是由C和C++编写的,不是java中的类。
负责加载java中最基础最核心的类,比如:rt.jar。
输出结果是:null
扩展加载器:ExtClassLoader
是由java编写的,是ClassLoader类的子类。
负责加载扩展包下的类。
应用类加载器:APPClassLoader
是由java编写的,是ClassLoader中的子类。
负责加载bin包和第三方jar包。
1. 2. 4 如何获得类加载器对象
- 通过Class对象的getClassLoader方法获得。
- 类名.class.getClassLoader()
1. 2. 5 类加载器的常用方法
ClassLoader getParent();
获得类加载器的父类加载器(没有继承关系,只用上下级的关系)
应用类加载器的父加载器:ExtClassLoader
扩展类加载器的父加载器:BootstrapClassLoader
URL getResource(String name);
根据资源文件名获得URL对象。默认从项目的src目录下查找,查找不到报异常.(本质是在bin目录下查找)
URL 常用方法:
String getpath();获取资源的绝对路径.src文件夹下的文件,在编译完成后会自动的复制一份到src同级目录 下的bin目录下.
Class类成员方法
method getMethod(String name,Class...pathname,
- 类加载器的代码示例
package com.alibaba.classDemo;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/*
* 如何获得类加载器对象
* 通过Class对象的getClassLoader方法获得。
类加载器的常用方法
* ClassLoader getParent();
* 获得父加载器对象(没有继承关系,只是上下级关系)
* 应用类加载器的父加载器:ExtClassLoader
* 扩展类加载器的父加载器:BootstrapClassLoader
* URL getResource(String name);
* 根据资源文件名获得URL对象
* 默认从项目根目下的src文件夹下查找指定资源文件,(本质是bin目录下查找)
* URL ==> 统一资源定位符 http://www.baid.com/image/aaa.png
* InputStream getResourceAsStream(String name);
* 根据资源文件获得与该资源相关的字节输入流
* 通过字节输入流对象就可以读取资源文件的内容
* 默认从项目根目下的src文件夹下查找指定资源文件,(本质是bin目录下查找)
*/
public class DemoClassLoader {
public static void main(String[] args) throws IOException {
test1();
test2();
}
private static void test2() throws IOException {
//* 通过Class对象的getClassLoader方法获得。
ClassLoader a1 =DemoClassLoader.class.getClassLoader();
//URL getResource(String name);* 根据资源文件名获得URL对象
URL u =a1.getResource("eclipse快捷键.txt");
///C:/copyright/eclipse/Day14后/bin/eclipse%e5%bf%ab%e6%8d%b7%e9%94%ae.txt
System.out.println(u.getPath());
//InputStream getResourceAsStream(String name);
// * 根据资源文件获得与该资源相关的字节输入流
InputStream input=a1.getResourceAsStream("eclipse快捷键.txt");
System.out.println(input.read());
}
public static void test1() throws IOException {
//* 通过Class对象的getClassLoader方法获得。
ClassLoader loader =DemoClassLoader.class.getClassLoader();
//获取Class对象的详细信息
System.out.println(loader);//jdk.internal.loader.ClassLoaders$AppClassLoader@726f3b58
//获得loader对象的父类加载器对象
ClassLoader c =loader.getParent();
System.out.println(c);//jdk.internal.loader.ClassLoaders$PlatformClassLoader@e6ea0c6
//获取c对象的父加载器对象
ClassLoader c1 =c.getParent();
System.out.println(c1);//null引导类加载器
}
}
2. 代理Proxy
2. 1. 代理模式的分类和作用
- 代理模式分为:静态代理和动态代理。
- 拦截真实对象的方法,增强真实对象的方法.
2. 2. 静态代理的实现
2. 2. 1 如何创建代理对象?
1. 真实对象:对象本身,如:明星
2. 代理对象:相当于真实对象的一个代理对象.如:经纪人
1) 拥有真实对象的成员变量
2) 通过构造方法传入真实对象
3) 可以改写真实对象的方法或对真实对象的方法进行拦截
3. 抽象对象:是真实对象与代理对象的共同接口
4. 调用者:使用真实对象的消费者,如:明星的粉丝.
package com.alibaba.classDemo;
//抽象对象
public interface Student {
//吃饭方法
void eat();
//学习方法
String Stud(String studName);
}
package Day17_;
/*
* 真实对象实现抽象类
* 重写抽象类的方法
*/
public class zhongStudent implements Student{
@Override
public void eat() {
System.out.println("吃中餐");
}
@Override
public String Stud(String studName) {
System.out.println("学习"+studName);
return "学习"+studName;
}
}
package com.alibaba.classDemo;
/*
* 代理对象
*/
public class ProxyStudent implements Student {
//拥有抽象对象的成员变量
private Student student;
public ProxyStudent(Student student) {
super();
this.student = student;
}
@Override
public void eat() {
System.out.println("中学生今天胃口好");
student.eat();
}
@Override
public String Stud(String studName) {
// System.out.println("中学生今天不学"+studName);
return "中学生今天上午不学"+studName;
}
}
package com.alibaba.classDemo;
/*
* 调用者
*/
public class mainFuns {
public static void main(String[] args) {
//创建真实对象
zhongStudent p1 =new zhongStudent();
//创建代理对象
Student p2=new ProxyStudent(p1);//中学生今天胃口好
//消费具体的方法
p2.eat();//吃中餐
System.out.println(p2.Stud("java"));//中学生今天上午不学java
}
}
优点:不需要修改目标对象就实现了目标对象功能的增加.
缺点:
真实对象必须对应一个代理对象,如果大量使用就会显得类很臃肿.
如果抽象对象中方法很多,那么真实对象和代理对象都要重写这些方法.
2. 3 动态代理
2. 3. 1 动态代理的特点
- 动态编写代理对象,不需要手动编写代理对象.
- 不需要编写目标对象中所有同名的方法.
2. 3. 2 动态代理相应的API
java
- 通过Proxy类的静态方法创建代理对象。
Proxy类创建代理的方法
public static Object newProxyInstance(ClassLoader loader,Class[]interfaces(),InvocationHanler h)
创建代理方法对象
loader:类加载器,传递真实对象的类加载器。
interfaces:真实对象所有实现的接口数组
h:具体的代理操作,InvocationHandler是一个接口,需要传入一个实现了此接口的实现类.
2. 3. 3 动态代理的使用步骤
- 先明确要代理的功能(方法)有哪些?
- 把要代理的功能(方法)定义接口中.
- 让被代理对象(真实对象)实现接口,重写接口中的方法.
- 创建
-
““java
““
3 Properties集合
- Properties集合是一个双列集合,实现了Map接口,继承Hashtable。
3. 1 Properties集合的特点
- 键和值都是String类型的,不支持泛型。和IO流有关的集合类,文件就加属性文件。
3. 2 属性文件命名要求
- 命名要求: XXXXX.Properties。
- 内容是:键=值,如name=password。
- 可以使用注释#,以#开头的行,则是注释行。
- 如果有空行,则被忽视。
- 一个键值对占据一行
3. 3 Properties集合常用方法
- 构造方法:Properties():无参的构造方法,创建一个空的属性对象。
- Object SetProperty(String key,String value):存储键值对,返回被覆盖的值。
- String getProperty(String key):根据键获得值。
- Object remove(Object key):根据键删除值。
- SetstringPropertyName() :返回此属性列表中的一对键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性中找到相同名称的键。
4 . Junit单元测试
4. 1 什么是Junit单元测试
- 在Java中,一个类就是一个单元。
- 单元测试就是开发者编写额的小段代码,用来测试某个类中的功能或者逻辑是否正确.
4.2 Junit的作用
- 帮助程序员对类中的方法进行有目的的测试,保证方法的正确性和稳定性。
- 可以让一个方法独立运行。
4. 3 Junit的使用步骤
- 编写业务类。
- 编写测试类。