1.类加载器:
1.1.类的加载:
程序要使用某个类时,该类还未被加载到内存,系统会通过加载,连接和初始化 三步来对这个类进行初始化。
加载:
将class读入到内存,并为他创建一个class对象。
连接:
验证 内部结构是否正确,是否和其他类保持一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化:
父类静态块-->子类静态块-->父类非静态方法-->父类构造方法-->子类非静态方法-->子类构造方法-->子类静态方法。
1.2.类的加载器
负责将.class加载到内存中,并为之生成对应的class 对象。
1.3.加载器的组成
Bootstrap ClassLoader 根类加载器。
也称为引导类加载器,负责Java核心类的加载。
2.反射
Java反射是类在运行状态中,可以获取类的所有属性和方法,并且能够调用任意一个属性和方法。这种动态获取信息以及动态调用对象的方法,称之为Java语言的反射机制。
反射可以比喻成,一个类在未创建的情况下,通过获取该类的Class字节码文件对象,而解剖使用Class类中的方法。
2.1.class类
获取Class对象的三种方式:
方式一:
通过Object类中的getObject()方法
Person p = new Person(); Class c = p.getClass();
方式二:
通过 类名.class 获取到字节码文件对象
通过 类名.class 获取到字节码文件对象
方式三:
通过Class类中的方法
Class c3 = Class.forName("cn.itcast_01_Reflect.Person");// 包名.类名
通过反射获取Person类的构造方法,方法,属性等...
package cn.itcast_01_Reflect; public class Person { //成员变量 public String name; public int age; private String address; //构造方法 public Person() { System.out.println("空参数构造方法"); } public Person(String name) { this.name = name; System.out.println("带有String的构造方法"); } //私有的构造方法 private Person(String name, int age){ this.name = name; this.age = age; System.out.println("带有String,int的构造方法"); } public Person(String name, int age, String address){ this.name = name; this.age = age; this.address = address; System.out.println("带有String, int, String的构造方法"); } //成员方法 //没有返回值没有参数的方法 public void method1(){ System.out.println("没有返回值没有参数的方法"); } //没有返回值,有参数的方法 public void method2(String name){ System.out.println("没有返回值,有参数的方法 name= "+ name); } //有返回值,没有参数 public int method3(){ System.out.println("有返回值,没有参数的方法"); return 123; } //有返回值,有参数的方法 public String method4(String name){ System.out.println("有返回值,有参数的方法"); return "哈哈" + name; } //私有方法 private void method5(){ System.out.println("私有方法"); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]"; } }
通过反射获取构造方法,并使用:
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { //获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person");//包名.类名 //获取所有的构造方法 //Constructor[] cons = c.getConstructors(); Constructor[] cons = c.getDeclaredConstructors(); for (Constructor con : cons) { System.out.println(con); } System.out.println("------------------------"); //获取一个构造方法 //public Person() Constructor con1 = c.getConstructor(null); System.out.println(con1); //public Person(String name) Constructor con2 = c.getConstructor(String.class); System.out.println(con2); //private Person(String name, int age) Constructor con3 = c.getDeclaredConstructor(String.class, int.class); System.out.println(con3); //public Person(String name, int age, String address) Constructor con4 = c.getDeclaredConstructor(String.class, int.class, String.class); System.out.println(con4); } }
通过反射获取构造方法,创建对象
1. 获取到Class对象
2. 获取指定的构造方法
3. 通过构造方法类Constructor中的方法,创建对象
public T newInstance(Object... initargs)
l 代码演示
public class ConstructorDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1,获取到Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person");//包名.类名 //2,获取指定的构造方法 //public Person() //Constructor con = c.getConstructor(null); //public Person(String name, int age, String address) Constructor con = c.getConstructor(String.class, int.class, String.class); //3,通过构造方法类中Constructor的方法,创建对象 //Object obj = con.newInstance(null); Object obj = con.newInstance("小明", 22, "哈尔滨"); //显示 System.out.println(obj); } }
通过反射获取 私有化的构造方法,创建对象
l 代码演示:
public class ConstructorDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1,获取到Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person");//包名.类名 //2,获取指定的构造方法 //private Person(String name, int age) Constructor con = c.getDeclaredConstructor(String.class, int.class); //3,暴力反射 con.setAccessible(true);//取消 Java 语言访问检查 //4,通过构造方法类中的功能,创建对象 Object obj = con.newInstance("小明", 23); System.out.println(obj); } }
通过反射获取 成员变量 并使用
在反射机制中,把类中的成员变量使用类Field表示。可通过Class类中提供的方法获取成员变量。
获取成员变量的代码演示:
public class FieldDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException { //获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person"); //获取成员变量 //多个变量 //Field[] fields = c.getFields(); Field[] fields = c.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("-----------------"); //一个变量 //public int age; Field ageField = c.getField("age"); System.out.println(ageField); //private String address Field addressField = c.getDeclaredField("address"); System.out.println(addressField); } }
通过反射 创建对象 , 获取指定的成员变量,进行赋值与获取值得操作。
l 代码演示:
public class FieldDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { //1,获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2,获取构造方法 //public Person(String name) Constructor con = c.getConstructor(String.class); //3,通过构造方法,创建对象 Object obj = con.newInstance("小明"); //4,获取指定的成员变量 //public String name; Field nameField = c.getField("name"); //public int age; Field ageField = c.getField("age"); //private String address; Field addressField = c.getDeclaredField("address"); addressField.setAccessible(true); //取消 Java 语言访问检查 //5,通过方法,给指定对象的指定成员变量赋值或者获取值 System.out.println("name = "+ nameField.get(obj)); System.out.println("age = "+ ageField.get(obj)); System.out.println("address = "+ addressField.get(obj)); //赋值 ageField.set(obj, 23); addressField.set(obj, "凯利广场"); System.out.println("------------------------"); System.out.println("name = "+ nameField.get(obj)); System.out.println("age = "+ ageField.get(obj)); System.out.println("address = "+ addressField.get(obj)); } }
通过反射获取成员方法,并使用
l 获取成员方法的代码演示:
public class MethodDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { //获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person"); //获取多个方法 //Method[] methods = c.getMethods(); Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("-----------------------"); //获取一个方法: //public void method1() Method method = c.getMethod("method1", null); System.out.println(method); //public String method4(String name){ method = c.getMethod("method4", String.class); System.out.println(method); //私有方法 //private void method5() method = c.getDeclaredMethod("method5", null); System.out.println(method); } }
通过反射,创建对象,调用指定的方法
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的方法
5. 执行找到的方法
public class MethodDemo2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1, 获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2,获取构造方法 //public Person(String name, int age, String address){ Constructor con = c.getConstructor(String.class, int.class, String.class); //3,通过构造方法,创建对象 Object obj = con.newInstance("小明", 23, "哈尔滨"); //4,获取指定的方法 //public void method1() 没有返回值没有参数的方法 //Method m1 = c.getMethod("method1", null); //public String method4(String name) Method m4 = c.getMethod("method4", String.class); //5,执行找到的方法 //m1.invoke(obj, null); Object result = m4.invoke(obj, "itcast"); System.out.println("result = " + result); } }
通过反射 创建对象, 调用指定的private 方法
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的方法
5. 开启暴力访问
6. 执行找到的方法
public class MethodDemo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1, 获取Class对象 Class c = Class.forName("cn.itcast_01_Reflect.Person"); //2,获取构造方法 //public Person(String name, int age, String address){ Constructor con = c.getConstructor(String.class, int.class, String.class); //3,通过构造方法,创建对象 Object obj = con.newInstance("小明", 23, "哈尔滨"); //4,获取指定的方法 //private void method5(){ Method m5 = c.getDeclaredMethod("method5", null); //5,开启暴力访问 m5.setAccessible(true); //6,执行找到的方法 m5.invoke(obj, null); } }
反射配置文件
l 通过反射配置文件,运行配置文件中指定类的对应方法
读取Peoperties.txt文件中的数据,通过反射技术,来完成Person对象的创建
Peoperties.txt文件内容如下:
className=cn.itcast_01_Reflect.Person
methodName=method5
l 读取配置文件,调用指定类中的对应方法
public class ReflectTest2 { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 通过Properties集合从文件中读取数据 Properties prop = new Properties(); // 读取文件中的数据到集合中 prop.load(new FileInputStream("properties.txt")); // 获取键所对应的值 String className = prop.getProperty("className"); System.out.println(className); // 1,获取Person.class 字节码文件对象 Class c = Class.forName(className); // 2,获取构造方法 // public Person(String name, int age, String address) Constructor con = c.getConstructor(String.class, int.class, String.class); // 3,创建对象 Object obj = con.newInstance("小明", 20, "中国"); System.out.println(obj); // 4,获取指定的方法 // private void method5(){} String methodName = prop.getProperty("methodName"); Method m5 = c.getDeclaredMethod(methodName, null); // 5,开启暴力访问 m5.setAccessible(true); // 6,执行找到的方法 m5.invoke(obj, null); } }
这样就可以了。