反射,工厂模式
该类不能运行,执行Test方法,需要空构造函数
demo3: 调用指定构造方法
demo2: 调用默认构造方法
demo1: 获得.class 字节码对象,对应Class对象. 3种方法
工厂模式: 使用接口, 接收通过工厂类返回来的实例对象. 工厂类通过读取配置文件,来决定实例化哪个类
package com.xiaofan.test; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import org.junit.Test; public class ClassTest { public ClassTest(int a) { }
// 类构造实例,调用指定构造方法 @Test public void demo3() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { // 已知类情况下,通过new 创建实例 ClassTest classTest = new ClassTest(10); // 1. 获得字节码对象 Class c = Class.forName("com.xiaofan.test.ClassTest"); // 2. 获得指定构造方法 Constructor constructor = c.getConstructor(int.class); // 3、调用构造方法 获得对象 Object o = constructor.newInstance(10); }
// 类构造实例,默认构造方法 @Test public void demo2() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // 已知类情况下,通过new 创建实例 ClassTest classTest = new ClassTest(10); // 未知类和对象情况下 String classDescription = "com.xiaofan.test.ClassTest"; Class c3 = Class.forName(classDescription); Object classTest2 = c3.newInstance(); // 执行默认构造方法 } // 获得一个.class 字节码文件 对应Class类对象 @Test public void demo1() throws ClassNotFoundException { // 已知类情况下 获得字节码对象 Class c1 = ClassTest.class; // 已知一个对象,但是不知道这个对象属于哪个类,获得字节码对象 Object o = new ArrayList(); Class c2 = o.getClass(); // 等价于 ArrayList.class // 未知类和对象情况下 String classDescription = "com.xiaofan.test.ClassTest"; Class c3 = Class.forName(classDescription); } }
-----------------------------------------------------------------------------------------------
通过反射获取成员变量,执行类中方法
package com.xiaofan.test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.junit.Test; public class FieldMethodTest { private int num; public void m(String s) { System.out.println("反射测试的方法!" + s); } /** * 通过反射的方式执行类中的方法 */ @Test public void demo2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { // 以前方式 FieldMethodTest fieldMethodTest = new FieldMethodTest(); fieldMethodTest.m("001"); // 1. 获得Class对象 Class c = Class.forName("com.xiaofan.test.FieldMethodTest"); // 2、获得对象 Object o = c.newInstance(); // 3. 获得m对象反射中Method对象 Method m = c.getMethod("m", String.class); // 4. 调用o对象m方法 m.invoke(o, "008"); } /** * 通过反射获取成员变量,修改私有变量是可见的 */ @Test public void demo1() throws ClassNotFoundException, SecurityException, NoSuchFieldException, InstantiationException, IllegalAccessException { // 以前方法操作变量 FieldMethodTest fieldMethodTest = new FieldMethodTest(); fieldMethodTest.num = 10; // 1、获得字节码文件 Class c = Class.forName("com.xiaofan.test.FieldMethodTest"); // 2、获得num成员变量 对应反射对象 Field Field[] fields = c.getFields(); // 获得所有public属性 System.out.println(fields.length); Field[] fields2 = c.getDeclaredFields(); //获得所有成员变量 System.out.println(fields2.length); Field field = c.getDeclaredField("num"); // 3. 为num 赋值 Object o = c.newInstance(); // 调用默认构造方法 // 修改私有变量是 可见的 field.setAccessible(true); field.set(o, 20); System.out.println(field.get(o)); } }
-------------------------------------------------------------------------------------------------------
自动装配
package com.xiaofan.test; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.junit.Test; public class AutowireTest { @Test public void demo1() throws Exception { Map<String, String> map = new HashMap<String, String>(); map.put("name", "小丽"); map.put("hobby", "音乐"); map.put("age", "20"); Person person = new Person(); autowire(person, map); System.out.println(person.getName()); System.out.println(person.getHobby()); User user = new User(); autowire(user, map); System.out.println(user.getName()); System.out.println(user.getAge()); } public void autowire(Object o, Map<String, String> map) throws Exception { // 获得map 所有key Set<String> keys = map.keySet(); // 获得Object中所有属性 // 获得Class对象 Class c = o.getClass(); // 获得所有属性 Field[] fields = c.getDeclaredFields(); for (Field field : fields) { // 获得属性名称 String fieldName = field.getName(); // 判断属性名称是否存在于map的key if (map.containsKey(fieldName)) { // 完成属性封装 String value = map.get(fieldName); // 修改私有属性可见性 field.setAccessible(true); field.set(o, value); } } } } class User { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } class Person { private String name; private String hobby; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } }
------------------------------------------------------------------------------------------------
package com.xiaofan.demo; import org.junit.Test; import com.xiaofan.demo.impl.Fenggong; import com.xiaofan.demo.impl.Liuqian; import com.xiaofan.demo.impl.Wangfei; import com.xiaofan.demo.impl.Yangliping; public class EveningParty { /** * 使用工厂模式,从配置文件中实例化所需要的对象 * @throws Exception */ @Test public void demo2() throws Exception { // 对于估计要做事情,定义接口 ---- 不变的 // 变化的是 实现类 // 1. 歌曲类 Singer singer = Factory.findSinger(); // 工厂 singer.sing(); // 2. 舞蹈类 Dancer dancer = Factory.findDancer(); dancer.dance(); // 3、语言类 Speaker speaker = Factory.findSpeaker(); speaker.speak(); // 4、动作类 Actor actor = Factory.findActor(); actor.action(); } /** * 传统方式,紧密耦合 */ @Test public void demo1() { // 对于估计要做事情,定义接口 ---- 不变的 // 变化的是 实现类 // 1. 歌曲类 Singer singer = new Wangfei(); // 紧密耦合 singer.sing(); // 2. 舞蹈类 Dancer dancer = new Yangliping(); dancer.dance(); // 3、语言类 Speaker speaker = new Fenggong(); speaker.speak(); // 4、动作类 Actor actor = new Liuqian(); actor.action(); } }
工厂类:
package com.xiaofan.demo; import java.util.ResourceBundle; import com.xiaofan.demo.impl.Liuqian; import com.xiaofan.demo.impl.Yangliping; import com.xiaofan.demo.impl.Zhaobenshan; public class Factory { public static Singer findSinger() throws Exception { // return new Wangfei(); // 上面是传统模式,下面使用工厂模式返回实例对象 // className = com.xiaofan.demo.impl.Zhangxueyou // ResourceBundle: 资源包类,可以使用指定的语言环境.使用类加载器的方式加载配置文件 String className = ResourceBundle.getBundle("party").getString("singer"); Class c = Class.forName(className); return (Singer) c.newInstance(); } public static Dancer findDancer() { return new Yangliping(); } public static Speaker findSpeaker() { return new Zhaobenshan(); } public static Actor findActor() { return new Liuqian(); } }
接口类(这里只paste了其中一个接口):
package com.xiaofan.demo; public interface Singer { public void sing(); }
接口实现类(这里只paste了其中一个实现类):
package com.xiaofan.demo.impl; import com.xiaofan.demo.Singer; public class Zhangxueyou implements Singer { @Override public void sing() { System.out.println("张学友 演唱 一路有你!"); } }
配置文件:
singer = com.xiaofan.demo.impl.Zhangxueyou dancer =com.xiaofan.demo.impl.Yangliping speaker = com.xiaofan.demo.impl.Fenggong actor =com.xiaofan.demo.impl.Liuqian
--------------------------------------------------------------------------------------------