多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 类加载机制与反射 ## 反射机制的概念 反射是 Java 中一个非常强大的工具,能够方便我们创建更加灵活的代码,这些代码可以在运行时进行装载。 类中有什么信息,利用反射机制就能获得什么信息,不过有前提,必须知道类的全名。 > 但是使用反射对系统的开销是比较大的。 ## 反射机制的作用 1. 在运行时判断一个对象所属的类; 2. 在运行时获取类的对象; 3. 在运行时访问 Java 对象的属性、方法、构造器等等。 ## 反射机制的优点和缺点 * 静态编译:在编译时就确定类型,绑定对象; * 动态编译:运行时确定类型,绑定对象。动态编译极大限度的发挥了Java的灵活性,体现了多态的概念,用于降低类之间的耦合; * 反射机制的优点:可以实现动态创建对象和编译; * 反射机制的缺点:对性能有影响。反射基本上是一种解释性的操作。我们告诉JVM,希望它做什么并满足我们的要求,这类操作总是慢于只直接执行相同的操作。 ## 反射机制的示例 **通过一个对象获得一个完整的包名和类名** ~~~ public class Client2 { public static void main(String[] args) { Demo demo = new Demo(); // 根据对象获取完整的包名和类名 System.out.println(demo.getClass().getName()); } } class Demo2 { } ~~~ **实例化Class类对象** ~~~ public class Client3 { public static void main(String[] args) throws ClassNotFoundException { // Class类是所有对象的元数据的类对象 Class<?> demo1 = null; Class<?> demo2 = null; Class<?> demo3 = null; demo1 = Class.forName("com.ntqingniao.reflect.Demo3"); demo2 = new Demo3().getClass(); demo3 = Demo3.class; System.out.println(demo1.getName()); System.out.println(demo2.getName()); System.out.println(demo3.getName()); } } class Demo3 { } ~~~ **通过Class实例化其他类的对象** ~~~ package com.ntqingniao.reflect; public class Client4 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class<?> demo = null; // 通过类全名创建Class对象(类型的工厂) demo = Class.forName("com.ntqingniao.reflect.Person"); // 调用工厂的newInstance()方法创建对象 Person per = (Person)demo.newInstance(); per.setName("Tom"); System.out.println(per); } } class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [" + (name != null ? "name=" + name + ", " : "") + "age=" + age + "]"; } } ~~~ > 如果把Person类中的无参构造函数取消,就会出现错误。 > 所以在编写使用Class实例化其他类对象的时候,一定要定义一个无参的构造器。 **通过Class调用类中的构造器** ~~~ // 获取该类的所有构造器对象 Constructor<?> cons[] = demo.getConstructors(); // 通过构造器对象的newInstance(Object.. params)可变参数方法构建对象 Person per1 = (Person)cons[0].newInstance(); Person per2 = (Person)cons[1].newInstance("Tom", 20); System.out.println(per1); System.out.println(per2); ~~~ **返回一个类实现的接口和继承的父类** ~~~ // 获取类的所有接口和直接父类方法 Class<?> inters[] = demo.getInterfaces(); Class<?> supers = demo.getSuperclass(); ~~~ **获取类的全部属性** ~~~ // 获取类的全部属性 Field[] fields = demo.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { // 获取权限修饰符 int mo = fields[i].getModifiers(); String priv = Modifier.toString(mo); // 数据类型 Class<?> type = fields[i].getType(); // 属性变量名 String name = fields[i].getName(); System.out.println(priv + " " + type.getName() + " " + name ) ; } ~~~ **调用类的方法** ~~~ Method method = demo.getMethod("getName"); method.invoke(demo.newInstance()); Person p = new Person(); Method method2 = demo.getMethod("getName", String.class); method2.invoke(p, "Reflect"); p.getName("Reflect"); ~~~ **调用类的Getter和Setter** ~~~ public class Client5 { public static void main(String[] args) throws Exception { Human tom = new Human(); setter(tom, "Name", "Tom", String.class); getter(tom, "Name"); System.out.println(tom); } public static void setter(Object obj, String attr, Object value, Class<?> type) throws Exception { Method method = obj.getClass().getMethod("set" + attr, type); method.invoke(obj, value); } public static void getter(Object obj, String attr) throws Exception { Method method = obj.getClass().getMethod("get" + attr); System.out.println(method.invoke(obj)); } } class Human { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Human [" + (name != null ? "name=" + name + ", " : "") + "age=" + age + "]"; } } ~~~ ## IOC原理 **设计模式之—工厂模式** 带配置文件的工厂模式设计 ~~~ //生产水果的工厂 public class FactoryReflect2 { public static Fruit getInstance(String key) { Fruit fruit = null; try { fruit = (Fruit) Class.forName(Init.getValue(key)).newInstance(); } catch (Exception e) { e.printStackTrace(); } return fruit; } public static void main(String[] args) { Fruit fruit = FactoryReflect2.getInstance("orange"); fruit.eat(); } } class Init { private static Properties pro = null; static { pro = new Properties(); try { pro.load(Init.class.getClassLoader().getResourceAsStream("fruit.properties")); } catch (Exception e) { // pro.setProperty("apple", "com.ntqingniao.ioc.Apple"); // pro.setProperty("orange", "com.ntqingniao.ioc.Orange"); // pro.setProperty("banana", "com.ntqingniao.ioc.Banana"); } } public static String getValue(String key) { return pro.getProperty(key); } } ~~~