一、类加载器:
分类:
1.启动类加载器(BoostrapClassLoad);
2.平台类加载器(Platform classloader):主要负责加载jdk的环境的依赖,以及大部分的JDK中的类;
3.系统类加载器(System classloader)加载程序员自己的写的类, 以及少部分的jdk的类。
重要功能:
可以读取字节码路径下的配置文件如:properties配置文件
使用方法:
InputStream in=classloader.getResourceAsStream(String path)
//返回值为字节流
获得类加载器对象的常用方法
方法二:类名.class.getClassLoad();
类名.class:得到该类的字节码对象
类字节码对象,有反向获取类加载器的方法
例如:
Test.class.getClassLoader()
//Test.class获取class对象,通过getClassLoader()方法获取类加载器
二、反射
反射的好处:可以更加灵活的创建对象,只需更改配置文件中的全类名就可以成功改变需要创建的对象。
1.获取某个字节码对象
Class.forName(“全类名”)
类名.class
对象.getClass
根据实际情况选择使用,不管哪一种只会获得一个字节码对象
例如:
Class clazz = Class.forName(classpath);
2.获取Constructor对象(需先获取字节码对象class)
获取方法:
2.1.Constructor[] getConstructors()方法:返回所有公共构造方法对象的数组;
2.2 Constructor[] getDeclaredConstructors()方法:返回所有的构造方法,包括公共构造和私有构造;
2.3 getConstructor()方法:返回单个公共构造方法。【小括号中,一定要跟构造方法的形参保持一致】(常用);
2.4 getDeclaredConstructor()方法:返回单个构造方法【括号中的形式也必须和构造方法一样】(常用);
例如:
Constructor constructor = clazz.getDeclaredConstructor();
//此处clazz是上方的字节码对象,配置文件中写的是哪个全类名最后用constructor创建对象,就会得到哪个类的对象。
配置文件(properties文件)中的内容:
classPath=cn.henanchengjian.Origan
注意:
被private修饰的成员,不能直接使用,如果用反射强行获取并使用 需要临时取消访问检查,需要调用constructor对象调用setAccessible(true);
例如:
constructor.setAccessible(true);
创建对象
利用newInstance()方法创建类的对象
Friut friut =(Friut) constructor.newInstance();
//friut是接口类,使用了多态
三、Properties
作用:
properties的父类是Map,所以Map集合的方法它都可以用。
专门用来处理字符串的键和值,而且可以和IO结合读写properties文件中的键值对
特有功能:
setProperty(String key, String value);//底层为put方法
String getProperty(String key);//底层为get方法
Set<String> stringPropertyNames();//底层为keySet方法
与IO结合的方法
load(InputStream in);
//我们没有给定编码, 他会用它的默认编码, ISO-8859-1不支持中文
load(FileReader fr);
//我们给定了字符流, 而字符流中内置编码, 他不会在用自己的编码了
四、使用反射的方式创建对象
1.创建properties文件,文件保存到src源文件夹下
文件内容及格式:
classPath=全类名(包名+类名);
//最好不要出现中文,出现中文则用propertie.load(转换流包装一下InputStreamReader)
2.类的实现
2.1首先使用properties读取文件
Properties properties = new Properties();
//使用类加载器读取字节码文件中的properties文件
InputStream in = Test.class.getClassLoader().getResourceAsStream("Friut.properties");
//如果文件中有中文则可以 properties.load(new InputStreamReader(in));
properties.load(in);
//获取文件中的全类名
String classpath = properties.getProperty("classPath");
2.2创建对象
// 用反射创建对象,先获取class对象
Class clazz = Class.forName(classpath);
//如果是准备创建有参构造,应该这样写:Constructor constructor1 = clazz.getConstructor(String.class, int.class);
Constructor constructor = clazz.getDeclaredConstructor();
// 私有构造需要先暂停类名检测
constructor.setAccessible(true);
// newInstance()括号中的参数和类中构造函数的参数类应该一样
Friut friut =(Friut) constructor.newInstance();
friut.Juice();